Commit d778492e authored by Ralf Jung's avatar Ralf Jung
Browse files

Merge branch 'ci/ralf/list-ra' into 'master'

add more lemmas to list RA and move it to iris-staging

See merge request iris/iris!654
parents d55f8339 bb4b373d
...@@ -22,6 +22,8 @@ lemma. ...@@ -22,6 +22,8 @@ lemma.
dedicated support from one of the involved maps/APIs. See dedicated support from one of the involved maps/APIs. See
[algebra.dyn_reservation_map](iris/algebra/dyn_reservation_map.v) for further [algebra.dyn_reservation_map](iris/algebra/dyn_reservation_map.v) for further
information. information.
* Demote the Camera structure on `list` to `iris_staging` since its composition
is not very well-behaved.
**Changes in `base_logic`:** **Changes in `base_logic`:**
......
...@@ -167,6 +167,9 @@ iris_heap_lang/lib/diverge.v ...@@ -167,6 +167,9 @@ iris_heap_lang/lib/diverge.v
iris_heap_lang/lib/arith.v iris_heap_lang/lib/arith.v
iris_heap_lang/lib/array.v iris_heap_lang/lib/array.v
iris_staging/algebra/list.v
iris_staging/base_logic/algebra.v
iris_deprecated/base_logic/auth.v iris_deprecated/base_logic/auth.v
iris_deprecated/base_logic/sts.v iris_deprecated/base_logic/sts.v
iris_deprecated/base_logic/viewshifts.v iris_deprecated/base_logic/viewshifts.v
......
From stdpp Require Export list. From stdpp Require Export list.
From iris.algebra Require Export cmra. From iris.algebra Require Export ofe.
From iris.algebra Require Import updates local_updates big_op. From iris.algebra Require Import big_op.
From iris.prelude Require Import options. From iris.prelude Require Import options.
Section ofe. Section ofe.
...@@ -165,396 +165,3 @@ Global Instance listOF_contractive F : ...@@ -165,396 +165,3 @@ Global Instance listOF_contractive F :
Proof. Proof.
by intros ? A1 ? A2 ? B1 ? B2 ? n f g Hfg; apply listO_map_ne, oFunctor_map_contractive. by intros ? A1 ? A2 ? B1 ? B2 ? n f g Hfg; apply listO_map_ne, oFunctor_map_contractive.
Qed. Qed.
(* CMRA. Only works if [A] has a unit! *)
Section cmra.
Context {A : ucmra}.
Implicit Types l : list A.
Local Arguments op _ _ !_ !_ / : simpl nomatch.
Local Instance list_op_instance : Op (list A) :=
fix go l1 l2 := let _ : Op _ := @go in
match l1, l2 with
| [], _ => l2
| _, [] => l1
| x :: l1, y :: l2 => x y :: l1 l2
end.
Local Instance list_pcore_instance : PCore (list A) := λ l, Some (core <$> l).
Local Instance list_valid_instance : Valid (list A) := Forall (λ x, x).
Local Instance list_validN_instance : ValidN (list A) := λ n, Forall (λ x, {n} x).
Lemma cons_valid l x : (x :: l) x l.
Proof. apply Forall_cons. Qed.
Lemma cons_validN n l x : {n} (x :: l) {n} x {n} l.
Proof. apply Forall_cons. Qed.
Lemma app_valid l1 l2 : (l1 ++ l2) l1 l2.
Proof. apply Forall_app. Qed.
Lemma app_validN n l1 l2 : {n} (l1 ++ l2) {n} l1 {n} l2.
Proof. apply Forall_app. Qed.
Lemma list_lookup_valid l : l i, (l !! i).
Proof.
rewrite {1}/valid /list_valid_instance Forall_lookup; split.
- intros Hl i. by destruct (l !! i) as [x|] eqn:?; [apply (Hl i)|].
- intros Hl i x Hi. move: (Hl i); by rewrite Hi.
Qed.
Lemma list_lookup_validN n l : {n} l i, {n} (l !! i).
Proof.
rewrite {1}/validN /list_validN_instance Forall_lookup; split.
- intros Hl i. by destruct (l !! i) as [x|] eqn:?; [apply (Hl i)|].
- intros Hl i x Hi. move: (Hl i); by rewrite Hi.
Qed.
Lemma list_lookup_op l1 l2 i : (l1 l2) !! i = l1 !! i l2 !! i.
Proof.
revert i l2. induction l1 as [|x l1]; intros [|i] [|y l2];
by rewrite /= ?left_id_L ?right_id_L.
Qed.
Lemma list_lookup_core l i : core l !! i = core (l !! i).
Proof.
rewrite /core /= list_lookup_fmap.
destruct (l !! i); by rewrite /= ?Some_core.
Qed.
Lemma list_lookup_included l1 l2 : l1 l2 i, l1 !! i l2 !! i.
Proof.
split.
{ intros [l Hl] i. exists (l !! i). by rewrite Hl list_lookup_op. }
revert l1. induction l2 as [|y l2 IH]=>-[|x l1] Hl.
- by exists [].
- destruct (Hl 0) as [[z|] Hz]; inversion Hz.
- by exists (y :: l2).
- destruct (IH l1) as [l3 ?]; first (intros i; apply (Hl (S i))).
destruct (Hl 0) as [[z|] Hz]; inversion_clear Hz; simplify_eq/=.
+ exists (z :: l3); by constructor.
+ exists (core x :: l3); constructor; by rewrite ?cmra_core_r.
Qed.
Definition list_cmra_mixin : CmraMixin (list A).
Proof.
apply cmra_total_mixin.
- eauto.
- intros n l l1 l2; rewrite !list_dist_lookup=> Hl i.
by rewrite !list_lookup_op Hl.
- intros n l1 l2 Hl; by rewrite /core /= Hl.
- intros n l1 l2; rewrite !list_dist_lookup !list_lookup_validN=> Hl ? i.
by rewrite -Hl.
- intros l. rewrite list_lookup_valid. setoid_rewrite list_lookup_validN.
setoid_rewrite cmra_valid_validN. naive_solver.
- intros n x. rewrite !list_lookup_validN. auto using cmra_validN_S.
- intros l1 l2 l3; rewrite list_equiv_lookup=> i.
by rewrite !list_lookup_op assoc.
- intros l1 l2; rewrite list_equiv_lookup=> i.
by rewrite !list_lookup_op comm.
- intros l; rewrite list_equiv_lookup=> i.
by rewrite list_lookup_op list_lookup_core cmra_core_l.
- intros l; rewrite list_equiv_lookup=> i.
by rewrite !list_lookup_core cmra_core_idemp.
- intros l1 l2; rewrite !list_lookup_included=> Hl i.
rewrite !list_lookup_core. by apply cmra_core_mono.
- intros n l1 l2. rewrite !list_lookup_validN.
setoid_rewrite list_lookup_op. eauto using cmra_validN_op_l.
- intros n l.
induction l as [|x l IH]=> -[|y1 l1] [|y2 l2] Hl Heq;
(try by exfalso; inversion Heq).
+ by exists [], [].
+ exists [], (x :: l); inversion Heq; by repeat constructor.
+ exists (x :: l), []; inversion Heq; by repeat constructor.
+ destruct (IH l1 l2) as (l1'&l2'&?&?&?),
(cmra_extend n x y1 y2) as (y1'&y2'&?&?&?);
[by inversion_clear Heq; inversion_clear Hl..|].
exists (y1' :: l1'), (y2' :: l2'); repeat constructor; auto.
Qed.
Canonical Structure listR := Cmra (list A) list_cmra_mixin.
Global Instance list_unit_instance : Unit (list A) := [].
Definition list_ucmra_mixin : UcmraMixin (list A).
Proof.
split.
- constructor.
- by intros l.
- by constructor.
Qed.
Canonical Structure listUR := Ucmra (list A) list_ucmra_mixin.
Global Instance list_cmra_discrete : CmraDiscrete A CmraDiscrete listR.
Proof.
split; [apply _|]=> l; rewrite list_lookup_valid list_lookup_validN=> Hl i.
by apply cmra_discrete_valid.
Qed.
Lemma list_core_id' l : ( x, x l CoreId x) CoreId l.
Proof.
intros Hyp. constructor. apply list_equiv_lookup=> i.
rewrite list_lookup_core.
destruct (l !! i) eqn:E; last done.
by eapply Hyp, elem_of_list_lookup_2.
Qed.
Global Instance list_core_id l : ( x : A, CoreId x) CoreId l.
Proof. intros Hyp; by apply list_core_id'. Qed.
End cmra.
Global Arguments listR : clear implicits.
Global Arguments listUR : clear implicits.
Global Instance list_singletonM {A : ucmra} : SingletonM nat A (list A) := λ n x,
replicate n ε ++ [x].
Section properties.
Context {A : ucmra}.
Implicit Types l : list A.
Implicit Types x y z : A.
Local Arguments op _ _ !_ !_ / : simpl nomatch.
Local Arguments cmra_op _ !_ !_ / : simpl nomatch.
Local Arguments ucmra_op _ !_ !_ / : simpl nomatch.
Lemma list_lookup_opM l mk i : (l ? mk) !! i = l !! i (mk = (.!! i)).
Proof. destruct mk; by rewrite /= ?list_lookup_op ?right_id_L. Qed.
Global Instance list_op_nil_l : LeftId (=) (@nil A) op.
Proof. done. Qed.
Global Instance list_op_nil_r : RightId (=) (@nil A) op.
Proof. by intros []. Qed.
Lemma list_op_app l1 l2 l3 :
(l1 ++ l3) l2 = (l1 take (length l1) l2) ++ (l3 drop (length l1) l2).
Proof.
revert l2 l3.
induction l1 as [|x1 l1]=> -[|x2 l2] [|x3 l3]; f_equal/=; auto.
Qed.
Lemma list_op_app_le l1 l2 l3 :
length l2 length l1 (l1 ++ l3) l2 = (l1 l2) ++ l3.
Proof. intros ?. by rewrite list_op_app take_ge // drop_ge // right_id_L. Qed.
Lemma list_lookup_validN_Some n l i x : {n} l l !! i {n} Some x {n} x.
Proof. move=> /list_lookup_validN /(_ i)=> Hl Hi; move: Hl. by rewrite Hi. Qed.
Lemma list_lookup_valid_Some l i x : l l !! i Some x x.
Proof. move=> /list_lookup_valid /(_ i)=> Hl Hi; move: Hl. by rewrite Hi. Qed.
Lemma list_length_op l1 l2 : length (l1 l2) = max (length l1) (length l2).
Proof. revert l2. induction l1; intros [|??]; f_equal/=; auto. Qed.
Lemma replicate_valid n (x : A) : x replicate n x.
Proof. apply Forall_replicate. Qed.
Global Instance list_singletonM_ne i :
NonExpansive (@list_singletonM A i).
Proof. intros n l1 l2 ?. apply Forall2_app; by repeat constructor. Qed.
Global Instance list_singletonM_proper i :
Proper (() ==> ()) (list_singletonM i) := ne_proper _.
Lemma elem_of_list_singletonM i z x : z ({[i := x]} : list A) z = ε z = x.
Proof.
rewrite elem_of_app elem_of_list_singleton elem_of_replicate. naive_solver.
Qed.
Lemma list_lookup_singletonM i x : ({[ i := x ]} : list A) !! i = Some x.
Proof. induction i; by f_equal/=. Qed.
Lemma list_lookup_singletonM_lt i i' x:
(i' < i)%nat ({[ i := x ]} : list A) !! i' = Some ε.
Proof. move: i'. induction i; intros [|i']; naive_solver auto with lia. Qed.
Lemma list_lookup_singletonM_gt i i' x:
(i < i')%nat ({[ i := x ]} : list A) !! i' = None.
Proof. move: i'. induction i; intros [|i']; naive_solver auto with lia. Qed.
Lemma list_lookup_singletonM_ne i j x :
i j
({[ i := x ]} : list A) !! j = None ({[ i := x ]} : list A) !! j = Some ε.
Proof. revert j; induction i; intros [|j]; naive_solver auto with lia. Qed.
Lemma list_singletonM_validN n i x : {n} ({[ i := x ]} : list A) {n} x.
Proof.
rewrite list_lookup_validN. split.
{ move=> /(_ i). by rewrite list_lookup_singletonM. }
intros Hx j; destruct (decide (i = j)); subst.
- by rewrite list_lookup_singletonM.
- destruct (list_lookup_singletonM_ne i j x) as [Hi|Hi]; first done;
rewrite Hi; by try apply (ucmra_unit_validN (A:=A)).
Qed.
Lemma list_singletonM_valid i x : ({[ i := x ]} : list A) x.
Proof.
rewrite !cmra_valid_validN. by setoid_rewrite list_singletonM_validN.
Qed.
Lemma list_singletonM_length i x : length {[ i := x ]} = S i.
Proof.
rewrite /singletonM /list_singletonM app_length replicate_length /=; lia.
Qed.
Lemma list_singletonM_core i (x : A) : core {[ i := x ]} @{list A} {[ i := core x ]}.
Proof.
rewrite /singletonM /list_singletonM.
by rewrite {1}/core /= fmap_app fmap_replicate (core_id_core ).
Qed.
Lemma list_singletonM_op i (x y : A) :
{[ i := x ]} {[ i := y ]} @{list A} {[ i := x y ]}.
Proof.
rewrite /singletonM /list_singletonM /=.
induction i; constructor; rewrite ?left_id; auto.
Qed.
Lemma list_alter_singletonM f i x :
alter f i ({[i := x]} : list A) = {[i := f x]}.
Proof.
rewrite /singletonM /list_singletonM /=. induction i; f_equal/=; auto.
Qed.
Global Instance list_singletonM_core_id i (x : A) :
CoreId x CoreId {[ i := x ]}.
Proof. by rewrite !core_id_total list_singletonM_core=> ->. Qed.
Lemma list_singletonM_snoc l x:
{[length l := x]} l l ++ [x].
Proof. elim: l => //= ?? <-. by rewrite left_id. Qed.
Lemma list_singletonM_included i x l:
{[i := x]} l ( x', l !! i = Some x' x x').
Proof.
rewrite list_lookup_included. split.
{ move /(_ i). rewrite list_lookup_singletonM option_included_total.
naive_solver. }
intros (y&Hi&?) j. destruct (Nat.lt_total j i) as [?|[->|?]].
- rewrite list_lookup_singletonM_lt //.
destruct (lookup_lt_is_Some_2 l j) as [z Hz].
{ trans i; eauto using lookup_lt_Some. }
rewrite Hz. by apply Some_included_2, ucmra_unit_least.
- rewrite list_lookup_singletonM Hi. by apply Some_included_2.
- rewrite list_lookup_singletonM_gt //. apply: ucmra_unit_least.
Qed.
(* Update *)
Lemma list_singletonM_updateP (P : A Prop) (Q : list A Prop) x :
x ~~>: P ( y, P y Q [y]) [x] ~~>: Q.
Proof.
rewrite !cmra_total_updateP=> Hup HQ n lf /list_lookup_validN Hv.
destruct (Hup n (default ε (lf !! 0))) as (y&?&Hv').
{ move: (Hv 0). by destruct lf; rewrite /= ?right_id. }
exists [y]; split; first by auto.
apply list_lookup_validN=> i.
move: (Hv i) Hv'. by destruct i, lf; rewrite /= ?right_id.
Qed.
Lemma list_singletonM_updateP' (P : A Prop) x :
x ~~>: P [x] ~~>: λ k, y, k = [y] P y.
Proof. eauto using list_singletonM_updateP. Qed.
Lemma list_singletonM_update x y : x ~~> y [x] ~~> [y].
Proof.
rewrite !cmra_update_updateP; eauto using list_singletonM_updateP with subst.
Qed.
Lemma app_updateP (P1 P2 Q : list A Prop) l1 l2 :
l1 ~~>: P1 l2 ~~>: P2
( k1 k2, P1 k1 P2 k2 length l1 = length k1 Q (k1 ++ k2))
l1 ++ l2 ~~>: Q.
Proof.
rewrite !cmra_total_updateP=> Hup1 Hup2 HQ n lf.
rewrite list_op_app app_validN=> -[??].
destruct (Hup1 n (take (length l1) lf)) as (k1&?&?); auto.
destruct (Hup2 n (drop (length l1) lf)) as (k2&?&?); auto.
exists (k1 ++ k2). rewrite list_op_app app_validN.
by destruct (HQ k1 k2) as [<- ?].
Qed.
Lemma app_update l1 l2 k1 k2 :
length l1 = length k1
l1 ~~> k1 l2 ~~> k2 l1 ++ l2 ~~> k1 ++ k2.
Proof. rewrite !cmra_update_updateP; eauto using app_updateP with subst. Qed.
Lemma cons_updateP (P1 : A Prop) (P2 Q : list A Prop) x l :
x ~~>: P1 l ~~>: P2 ( y k, P1 y P2 k Q (y :: k)) x :: l ~~>: Q.
Proof.
intros. eapply (app_updateP _ _ _ [x]);
naive_solver eauto using list_singletonM_updateP'.
Qed.
Lemma cons_updateP' (P1 : A Prop) (P2 : list A Prop) x l :
x ~~>: P1 l ~~>: P2 x :: l ~~>: λ k, y k', k = y :: k' P1 y P2 k'.
Proof. eauto 10 using cons_updateP. Qed.
Lemma cons_update x y l k : x ~~> y l ~~> k x :: l ~~> y :: k.
Proof. rewrite !cmra_update_updateP; eauto using cons_updateP with subst. Qed.
Lemma list_middle_updateP (P : A Prop) (Q : list A Prop) l1 x l2 :
x ~~>: P ( y, P y Q (l1 ++ y :: l2)) l1 ++ x :: l2 ~~>: Q.
Proof.
intros. eapply app_updateP.
- by apply cmra_update_updateP.
- by eapply cons_updateP', cmra_update_updateP.
- naive_solver.
Qed.
Lemma list_middle_update l1 l2 x y : x ~~> y l1 ++ x :: l2 ~~> l1 ++ y :: l2.
Proof.
rewrite !cmra_update_updateP=> ?; eauto using list_middle_updateP with subst.
Qed.
(* FIXME
Lemma list_middle_local_update l1 l2 x y ml :
x ~l~> y @ ml ≫= (.!! length l1) →
l1 ++ x :: l2 ~l~> l1 ++ y :: l2 @ ml.
Proof.
intros [Hxy Hxy']; split.
- intros n; rewrite !list_lookup_validN=> Hl i; move: (Hl i).
destruct (lt_eq_lt_dec i (length l1)) as [[?|?]|?]; subst.
+ by rewrite !list_lookup_opM !lookup_app_l.
+ rewrite !list_lookup_opM !list_lookup_middle // !Some_op_opM; apply (Hxy n).
+ rewrite !(cons_middle _ l1 l2) !assoc.
rewrite !list_lookup_opM !lookup_app_r !app_length //=; lia.
- intros n mk; rewrite !list_lookup_validN !list_dist_lookup => Hl Hl' i.
move: (Hl i) (Hl' i).
destruct (lt_eq_lt_dec i (length l1)) as [[?|?]|?]; subst.
+ by rewrite !list_lookup_opM !lookup_app_l.
+ rewrite !list_lookup_opM !list_lookup_middle // !Some_op_opM !inj_iff.
apply (Hxy' n).
+ rewrite !(cons_middle _ l1 l2) !assoc.
rewrite !list_lookup_opM !lookup_app_r !app_length //=; lia.
Qed.
Lemma list_singleton_local_update i x y ml :
x ~l~> y @ ml ≫= (.!! i) → {[ i := x ]} ~l~> {[ i := y ]} @ ml.
Proof. intros; apply list_middle_local_update. by rewrite replicate_length. Qed.
*)
Lemma list_alloc_singletonM_local_update x l :
x (l, ε) ~l~> (l ++ [x], {[length l := x]}).
Proof.
move => ?.
have -> : ({[length l := x]} {[length l := x]} ε) by rewrite right_id.
rewrite -list_singletonM_snoc. apply op_local_update => ??.
rewrite list_singletonM_snoc app_validN cons_validN. split_and? => //; [| constructor].
by apply cmra_valid_validN.
Qed.
End properties.
(** Functor *)
Global Instance list_fmap_cmra_morphism {A B : ucmra} (f : A B)
`{!CmraMorphism f} : CmraMorphism (fmap f : list A list B).
Proof.
split; try apply _.
- intros n l. rewrite !list_lookup_validN=> Hl i. rewrite list_lookup_fmap.
by apply (cmra_morphism_validN (fmap f : option A option B)).
- intros l. apply Some_proper. rewrite -!list_fmap_compose.
apply list_fmap_equiv_ext, cmra_morphism_core, _.
- intros l1 l2. apply list_equiv_lookup=>i.
by rewrite list_lookup_op !list_lookup_fmap list_lookup_op cmra_morphism_op.
Qed.
Program Definition listURF (F : urFunctor) : urFunctor := {|
urFunctor_car A _ B _ := listUR (urFunctor_car F A B);
urFunctor_map A1 _ A2 _ B1 _ B2 _ fg := listO_map (urFunctor_map F fg)
|}.
Next Obligation.
by intros F A1 ? A2 ? B1 ? B2 ? n f g Hfg; apply listO_map_ne, urFunctor_map_ne.
Qed.
Next Obligation.
intros F A ? B ? x. rewrite /= -{2}(list_fmap_id x).
apply list_fmap_equiv_ext=>y. apply urFunctor_map_id.
Qed.
Next Obligation.
intros F A1 ? A2 ? A3 ? B1 ? B2 ? B3 ? f g f' g' x. rewrite /= -list_fmap_compose.
apply list_fmap_equiv_ext=>y; apply urFunctor_map_compose.
Qed.
Global Instance listURF_contractive F :
urFunctorContractive F urFunctorContractive (listURF F).
Proof.
by intros ? A1 ? A2 ? B1 ? B2 ? n f g Hfg; apply listO_map_ne, urFunctor_map_contractive.
Qed.
Program Definition listRF (F : urFunctor) : rFunctor := {|
rFunctor_car A _ B _ := listR (urFunctor_car F A B);
rFunctor_map A1 _ A2 _ B1 _ B2 _ fg := listO_map (urFunctor_map F fg)
|}.
Solve Obligations with apply listURF.
Global Instance listRF_contractive F :
urFunctorContractive F rFunctorContractive (listRF F).
Proof. apply listURF_contractive. Qed.
...@@ -59,14 +59,6 @@ Section list_ofe. ...@@ -59,14 +59,6 @@ Section list_ofe.
Proof. uPred.unseal; constructor=> n x ?. apply list_dist_lookup. Qed. Proof. uPred.unseal; constructor=> n x ?. apply list_dist_lookup. Qed.
End list_ofe. End list_ofe.
Section list_cmra.
Context {A : ucmra}.
Implicit Types l : list A.
Lemma list_validI l : l i, (l !! i).
Proof. uPred.unseal; constructor=> n x ?. apply list_lookup_validN. Qed.
End list_cmra.
Section excl. Section excl.
Context {A : ofe}. Context {A : ofe}.
Implicit Types a b : A. Implicit Types a b : A.
......
This diff is collapsed.
(* This is just an integration file for [iris_staging.algebra.list];
both should be stabilized together. *)
From iris.algebra Require Import cmra.
From iris.staging.algebra Require Import list.
From iris.base_logic Require Import bi derived.
From iris.prelude Require Import options.
Section upred.
Context {M : ucmra}.
(* Force implicit argument M *)
Notation "P ⊢ Q" := (bi_entails (PROP:=uPredI M) P%I Q%I).
Notation "P ⊣⊢ Q" := (equiv (A:=uPredI M) P%I Q%I).
Section list_cmra.
Context {A : ucmra}.
Implicit Types l : list A.
Lemma list_validI l : l i, (l !! i).
Proof. uPred.unseal; constructor=> n x ?. apply list_lookup_validN. Qed.
End list_cmra.
End upred.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment