Skip to content
Snippets Groups Projects
Commit c54aa817 authored by Ralf Jung's avatar Ralf Jung
Browse files

Merge branch 'robbert/list_cofe' into 'master'

A more intuitive proof that lists from a COFE

See merge request iris/iris!239
parents 231b47e8 3c9e6825
No related branches found
No related tags found
No related merge requests found
...@@ -12,5 +12,5 @@ install: [make "install"] ...@@ -12,5 +12,5 @@ install: [make "install"]
remove: ["rm" "-rf" "%{lib}%/coq/user-contrib/iris"] remove: ["rm" "-rf" "%{lib}%/coq/user-contrib/iris"]
depends: [ depends: [
"coq" { (>= "8.7.1" & < "8.10~") | (= "dev") } "coq" { (>= "8.7.1" & < "8.10~") | (= "dev") }
"coq-stdpp" { (= "1.2.0") | (= "dev") } "coq-stdpp" { (= "dev.2019-05-03.0.09f69b7c") | (= "dev") }
] ]
...@@ -19,6 +19,8 @@ Global Instance length_ne n : Proper (dist n ==> (=)) (@length A) := _. ...@@ -19,6 +19,8 @@ Global Instance length_ne n : Proper (dist n ==> (=)) (@length A) := _.
Global Instance tail_ne : NonExpansive (@tail A) := _. Global Instance tail_ne : NonExpansive (@tail A) := _.
Global Instance take_ne : NonExpansive (@take A n) := _. Global Instance take_ne : NonExpansive (@take A n) := _.
Global Instance drop_ne : NonExpansive (@drop A n) := _. Global Instance drop_ne : NonExpansive (@drop A n) := _.
Global Instance head_ne : NonExpansive (head (A:=A)).
Proof. destruct 1; by constructor. Qed.
Global Instance list_lookup_ne i : Global Instance list_lookup_ne i :
NonExpansive (lookup (M:=list A) i). NonExpansive (lookup (M:=list A) i).
Proof. intros ????. by apply dist_option_Forall2, Forall2_lookup. Qed. Proof. intros ????. by apply dist_option_Forall2, Forall2_lookup. Qed.
...@@ -44,6 +46,13 @@ Proof. intros ????; by apply dist_option_Forall2, Forall2_last. Qed. ...@@ -44,6 +46,13 @@ Proof. intros ????; by apply dist_option_Forall2, Forall2_last. Qed.
Global Instance resize_ne n : Global Instance resize_ne n :
NonExpansive2 (@resize A n) := _. NonExpansive2 (@resize A n) := _.
Lemma list_dist_cons_inv_l n x l k :
x :: l {n} k y k', x {n} y l {n} k' k = y :: k'.
Proof. apply Forall2_cons_inv_l. Qed.
Lemma list_dist_cons_inv_r n l k y :
l {n} y :: k x l', x {n} y l' {n} k l = x :: l'.
Proof. apply Forall2_cons_inv_r. Qed.
Definition list_ofe_mixin : OfeMixin (list A). Definition list_ofe_mixin : OfeMixin (list A).
Proof. Proof.
split. split.
...@@ -54,28 +63,30 @@ Proof. ...@@ -54,28 +63,30 @@ Proof.
Qed. Qed.
Canonical Structure listC := OfeT (list A) list_ofe_mixin. Canonical Structure listC := OfeT (list A) list_ofe_mixin.
Program Definition list_chain (** To define [compl : chain (list A) → list A] we make use of the fact that
(c : chain listC) (x : A) (k : nat) : chain A := given a given chain [c0, c1, c2, ...] of lists, the list [c0] completely
{| chain_car n := default x (c n !! k) |}. determines the shape (i.e. the length) of all lists in the chain. So, the
Next Obligation. intros c x k n i ?. by rewrite /= (chain_cauchy c n i). Qed. [compl] operation is defined by structural recursion on [c0], and takes the
Definition list_compl `{!Cofe A} : Compl listC := λ c, completion of the elements of all lists in the chain point-wise. We use [head]
match c 0 with and [tail] as the inverse of [cons]. *)
Fixpoint list_compl_go `{!Cofe A} (c0 : list A) (c : chain listC) : listC :=
match c0 with
| [] => [] | [] => []
| x :: _ => compl list_chain c x <$> seq 0 (length (c 0)) | x :: c0 => compl (chain_map (default x head) c) :: list_compl_go c0 (chain_map tail c)
end. end.
Global Program Instance list_cofe `{!Cofe A} : Cofe listC := Global Program Instance list_cofe `{!Cofe A} : Cofe listC :=
{| compl := list_compl |}. {| compl c := list_compl_go (c 0) c |}.
Next Obligation. Next Obligation.
intros ? n c; rewrite /compl /list_compl. intros ? n c; rewrite /compl.
destruct (c 0) as [|x l] eqn:Hc0 at 1. assert (c 0 {0} c n) as Hc0 by (symmetry; apply chain_cauchy; lia).
{ by destruct (chain_cauchy c 0 n); auto with lia. } revert Hc0. generalize (c 0)=> c0. revert c.
rewrite -(λ H, length_ne _ _ _ (chain_cauchy c 0 n H)); last lia. induction c0 as [|x c0 IH]=> c Hc0 /=.
apply Forall2_lookup=> i. rewrite -dist_option_Forall2 list_lookup_fmap. { by inversion Hc0. }
destruct (decide (i < length (c n))); last first. apply list_dist_cons_inv_l in Hc0 as (x' & xs' & Hx & Hc0 & Hcn).
{ rewrite lookup_seq_ge ?lookup_ge_None_2; auto with lia. } rewrite Hcn. f_equiv.
rewrite lookup_seq //= (conv_compl n (list_chain c _ _)) /=. - by rewrite conv_compl /= Hcn /=.
destruct (lookup_lt_is_Some_2 (c n) i) as [? Hcn]; first done. - rewrite IH /= ?Hcn //.
by rewrite Hcn.
Qed. Qed.
Global Instance list_ofe_discrete : OfeDiscrete A OfeDiscrete listC. Global Instance list_ofe_discrete : OfeDiscrete A OfeDiscrete listC.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment