diff --git a/coq/ra/_CoqProject b/coq/ra/_CoqProject index e65919141ca07c463a1db6177a5347bcef7befac..83a5e928c81acd3753ef30af22c4168a957219d7 100644 --- a/coq/ra/_CoqProject +++ b/coq/ra/_CoqProject @@ -1,4 +1,5 @@ -Q . ra +infrastructure.v machine.v lang.v tactics.v diff --git a/coq/ra/infrastructure.v b/coq/ra/infrastructure.v new file mode 100644 index 0000000000000000000000000000000000000000..9c55f8ce2c8836389feadefd318f54a3ecc5bd0b --- /dev/null +++ b/coq/ra/infrastructure.v @@ -0,0 +1,360 @@ +From mathcomp Require Import ssreflect ssrbool seq. +From iris.prelude Require Export strings list numbers. +From iris.prelude Require Export gmap finite mapset. +Global Generalizable All Variables. +Global Set Automatic Coercions Import. +Global Set Asymmetric Patterns. +Global Set Bullet Behavior "Strict Subproofs". +From Coq Require Export Utf8. +Instance injective_dec_eq + `{H : ∀ x y : A, Decision (x = y)} {B : Type} + f (g : A -> option B) (Inj : ∀ x, g (f x) = Some x) : ∀ x y : B, Decision (x = y) | 1000. +Proof. + move => x y. case: (decide (f x = f y)). + - move/(f_equal g). rewrite !Inj => [[]]. by left. + - move => NEq. right => Eq. apply: NEq. by rewrite Eq. +Qed. + +Class Extension A := extension : relation A. +Instance: Params (@extension) 2. +Infix "⊑" := extension (at level 70) : C_scope. +Notation "(⊑)" := extension (only parsing) : C_scope. +Notation "( X ⊑ )" := (extension X) (only parsing) : C_scope. +Notation "( ⊑ X )" := (λ Y, Y ⊑ X) (only parsing) : C_scope. +Infix "⊑*" := (Forall2 (⊑)) (at level 70) : C_scope. +Notation "(⊑*)" := (Forall2 (⊑)) (only parsing) : C_scope. +Infix "⊑**" := (Forall2 (⊑*)) (at level 70) : C_scope. +Infix "⊑1*" := (Forall2 (λ p q, p.1 ⊑ q.1)) (at level 70) : C_scope. +Infix "⊑2*" := (Forall2 (λ p q, p.2 ⊑ q.2)) (at level 70) : C_scope. +Infix "⊑1**" := (Forall2 (λ p q, p.1 ⊑* q.1)) (at level 70) : C_scope. +Infix "⊑2**" := (Forall2 (λ p q, p.2 ⊑* q.2)) (at level 70) : C_scope. + +Class StrictExtension A := strict_extension : relation A. +Instance: Params (@strict_extension) 2. +Infix "âŠ" := strict_extension (at level 70) : C_scope. +Notation "(âŠ)" := strict_extension (only parsing) : C_scope. +Notation "( X ⊠)" := (strict_extension X) (only parsing) : C_scope. +Notation "( ⊠X )" := (λ Y, Y ⊠X) (only parsing) : C_scope. +Infix "âŠ*" := (Forall2 (âŠ)) (at level 70) : C_scope. +Notation "(âŠ*)" := (Forall2 (âŠ)) (only parsing) : C_scope. +Infix "âŠ**" := (Forall2 (âŠ*)) (at level 70) : C_scope. +Infix "âŠ1*" := (Forall2 (λ p q, p.1 ⊠q.1)) (at level 70) : C_scope. +Infix "âŠ2*" := (Forall2 (λ p q, p.2 ⊠q.2)) (at level 70) : C_scope. +Infix "âŠ1**" := (Forall2 (λ p q, p.1 âŠ* q.1)) (at level 70) : C_scope. +Infix "âŠ2**" := (Forall2 (λ p q, p.2 âŠ* q.2)) (at level 70) : C_scope. + +Class Join A := join : A → A → A. +Instance: Params (@join) 2. +Infix "⊔" := join (at level 50, left associativity) : C_scope. +Notation "(⊔)" := join (only parsing) : C_scope. +Notation "( x ⊔)" := (join x) (only parsing) : C_scope. +Notation "(⊔ x )" := (λ y, join y x) (only parsing) : C_scope. +Infix "⊔*" := (zip_with (⊔)) (at level 50, left associativity) : C_scope. +Notation "(⊔*)" := (zip_with (⊔)) (only parsing) : C_scope. +Infix "⊔**" := (zip_with (zip_with (⊔))) + (at level 50, left associativity) : C_scope. +Infix "⊔*⊔**" := (zip_with (prod_zip (⊔) (⊔*))) + (at level 50, left associativity) : C_scope. + + +Class JoinSemiLattice A `{Extension A, Join A} : Prop := { + join_semi_lattice_pre :>> PreOrder (⊑); + join_ext_l X Y : X ⊑ X ⊔ Y; + join_ext_r X Y : Y ⊑ X ⊔ Y; + join_least X Y Z : X ⊑ Z → Y ⊑ Z → X ⊔ Y ⊑ Z +}. + +Instance JSL_Comm `{E : Extension A} `{J : Join A} `{@PartialOrder A (⊑)} `{@JoinSemiLattice A E J} : @Comm A _ (=) (⊔). +Proof. + move => ? ?. + apply: anti_symm; apply: join_least; by eauto using join_ext_l, join_ext_r. +Qed. + +Instance JSL_Assoc `{E : Extension A} `{J : Join A} `{@PartialOrder A (⊑)} `{@JoinSemiLattice A E J} : @Assoc A (=) (⊔). +Proof. + move => ? ? ?. + apply: anti_symm; repeat apply: join_least; + by eauto using PreOrder_Transitive, join_ext_l, join_ext_r. +Qed. + +(* Generic Instances for Extension, Join and JoinSemiLattice *) +Instance prod_Extension `{Extension A} `{Extension B} : Extension (A * B) := + λ p1 p2, p1.1 ⊑ p2.1 ∧ p1.2 ⊑ p2.2. +Instance prod_PreOrder `{Extension A} `{Extension B} `{PreOrder A (⊑)} `{PreOrder B (⊑)} : @PreOrder (A * B) (⊑). +Proof. + econstructor. + - move => ?; cbv; split; by apply PreOrder_Reflexive. + - move => ? ? ? [H11 H12] [H21 H22]; split. + + by apply (PreOrder_Transitive _ _ _ H11 H21). + + by apply (PreOrder_Transitive _ _ _ H12 H22). +Qed. + +Instance prod_PartialOrder `{Extension A} `{Extension B} `{PartialOrder A (⊑)} `{PartialOrder B (⊑)} : @PartialOrder (A * B) (⊑). +Proof. + econstructor. + - by apply prod_PreOrder. + - move => [? ?] [? ?] [? ?] [? ?]. f_equal; by apply: anti_symm. +Qed. + +Instance prod_Join `{Join A} `{Join B} : Join (A * B) := + λ p1 p2, (p1.1 ⊔ p2.1, p1.2 ⊔ p2.2). +Instance prod_JSL `{JoinSemiLattice A} `{JoinSemiLattice B} : JoinSemiLattice (A * B). +Proof. + econstructor. + - exact: prod_PreOrder. + - move => ? ?; split; by apply join_ext_l. + - move => ? ?; split; by apply join_ext_r. + - move => ? ? ? [? ?] [? ?]. split; by apply join_least. +Qed. + +Instance option_Extension `{Extension T} : Extension (option T) := + λ o1 o2, match o1 with + | None => True + | Some t1 => match o2 with + | None => False + | Some t2 => t1 ⊑ t2 + end + end. + +Instance option_StrictExtension `{StrictExtension T} : StrictExtension (option T) := + λ o1 o2, match o1 with + | None => match o2 with + | None => False + | Some t2 => True + end + | Some t1 => match o2 with + | None => False + | Some t2 => t1 ⊠t2 + end + end. + +Instance option_StrictOrder `{StrictExtension T} `{StrictOrder T (âŠ)} : @StrictOrder (option T) (âŠ). +Proof. + econstructor. + - move => ?. cbv; repeat case_match => //. by apply: StrictOrder_Irreflexive. + - move => ? ? ?. cbv; repeat case_match => //. by apply: StrictOrder_Transitive. +Qed. + +Instance option_Join `{Join T} : Join (option T) := + λ o1 o2, match o1 with + | None => o2 + | Some t1 => match o2 with + | None => o1 + | Some t2 => Some $ t1 ⊔ t2 + end + end. +Instance option_PreOrder `{Extension T} `{PreOrder T (⊑)} : @PreOrder (option T) (⊑). +Proof. + econstructor. + - move => ?; cbv; repeat case_match => //. + exact: PreOrder_Reflexive. + - move => ? ? ?; cbv; repeat case_match => //. + exact: PreOrder_Transitive. +Qed. + +Instance option_PartialOrder `{Extension T} `{PartialOrder T (⊑)} : @PartialOrder (option T) (⊑). +Proof. + econstructor. + - by eauto with typeclass_instances. + - move => [?|] [?|] //; cbv => ? ?. f_equal. exact: anti_symm. +Qed. + +Instance option_Reflexive `{Extension T} `{Reflexive T (⊑)} : @Reflexive (option T) (⊑). +Proof. move => ?. cbv. by case_match. Qed. + +Instance option_AntiSymm `{Extension T} `{AntiSymm T (=) (⊑)} : AntiSymm (=) ((⊑) : relation (option T)). +Proof. + move => ? ?; cbv; repeat case_match => //; move => H1 H2. apply/f_equal. + by apply (@anti_symm _ _ _ H0). +Qed. + +Instance option_Comm `{Join T} `{@Comm T _ (=) join} : @Comm (option T) _ (=) (join). +Proof. + move => ? ?; cbv; repeat case_match => //. f_equal. by apply comm. +Qed. + +(* Instance option_Assoc `{Join T} `{@Assoc T (=) join} : @Assoc (option T) (=) (join). *) +(* Proof. *) +(* move => ? ? ?. cbv; repeat case_match => //; f_equal; simplify_option_eq. *) +(* - by apply assoc. *) +(* - reflexivity. *) +(* - reflexivity. *) +(* Qed. *) + +Instance option_JSL `{JoinSemiLattice T} : JoinSemiLattice (option T). +Proof. + econstructor. + - exact: option_PreOrder. + - move => ? ?. cbv; repeat case_match => //; simplify_option_eq. + + by apply join_ext_l. + + by apply PreOrder_Reflexive. + - move => ? ?. cbv; repeat case_match => //; simplify_option_eq. + + by apply join_ext_r. + + by apply PreOrder_Reflexive. + - move => ? ? ?; cbv; repeat case_match => //; simplify_option_eq. + by apply join_least. +Qed. + +(* Some auxilliary lemmas about option instances *) +Lemma option_ext_is_Some `{Extension T} (o1 o2 : option T) : o1 ⊑ o2 -> is_Some o1 -> is_Some o2. +Proof. + cbv; (repeat case_match). + - by eauto. + - by eauto. + - by move => _ [] //. +Qed. + +Lemma join_None `{Join T} (o1 : option T) : o1 ⊔ None = o1. +Proof. by cbv; repeat case_match. Qed. +Lemma option_subseteq_None_l `{Extension T} (o1 o2 : option T) : o1 ⊑ None ↔ o1 = None. +Proof. by cbv; repeat case_match. Qed. + + +(* Positive instances *) +Instance positive_Extension : Extension positive := (≤)%positive. +Instance positive_StrictExtension : StrictExtension positive := (<)%positive. +Instance positive_Join : Join positive := Pos.max. +Instance positive_PreOrder : PreOrder (⊑)%positive. +Proof. + econstructor; unfold extension, positive_Extension; + by eauto using Pos.le_refl, Pos.le_trans. +Qed. +Instance positive_PartialOrder : PartialOrder (⊑)%positive. +Proof. + econstructor. + - by eauto with typeclass_instances. + - exact: Pos.le_antisym. +Qed. +Instance positive_StrictOrder : StrictOrder (âŠ)%positive. +Proof. + econstructor; unfold strict_extension, positive_StrictExtension. + - move => ? ?. exact: Pos.lt_irrefl. + - exact: Pos.lt_trans. +Qed. +Instance positive_Total : Total (⊑)%positive. +Proof. + move => x y. case: (decide (x ≤ y)%positive); try tauto. + move/Pos.lt_nle/Pos.lt_le_incl. tauto. +Qed. + +Instance positive_Reflexive : Reflexive (⊑)%positive. +Proof. exact: Pos.le_refl. Qed. +Instance positive_AntiSymm : AntiSymm (=) (⊑)%positive. +Proof. exact: Pos.le_antisym. Qed. +(* Instance positive_Comm : Comm (=) (join)%positive. *) +(* Proof. exact: Pos.max_comm. Qed. *) +(* Instance positive_Assoc : Assoc (=) (join)%positive. *) +(* Proof. exact: Pos.max_assoc. Qed. *) + +Instance poisitive_JSL : JoinSemiLattice positive. +Proof. + econstructor. + - by eauto with typeclass_instances. + - move => ? ?. exact: Pos.le_max_l. + - move => ? ?. exact: Pos.le_max_r. + - move => ? ? ?. exact: Pos.max_lub. +Qed. + + +(* gmap instances *) +Instance gmap_countable `{Countable K} `{Countable A} : Countable (gmap K A) := + injective_countable (map_to_list : _ -> list (K * A)) + ((λ l : list (_ * _), Some (map_of_list l)) : list _ -> option _) _. +Proof. + intros. f_equal. exact: map_of_to_list. +Qed. + +Instance gmap_Join `{Countable K} `{Join A} : Join (gmap K A) := + union_with (λ a1 a2, Some $ a1 ⊔ a2). + +Lemma lookup_join `{Countable K} `{Join A} (f1 f2 : gmap K A) k : (f1 ⊔ f2) !! k = f1 !! k ⊔ f2 !! k. +Proof. + rewrite lookup_union_with. + by do 2!case: (_ !! k). +Qed. + +Instance gmap_Assoc `{Countable K} `{Join A} `{@Assoc A (=) join} : @Assoc (gmap K A) (=) join. +Proof. + move => ? ? ?. apply: map_eq => k. + rewrite !lookup_union_with. + repeat case: (_ !! k) => //=. + move => ? ? ?. f_equal. by apply assoc. +Qed. + +Instance gmap_Extension `{Countable K} `{Extension A} : Extension (gmap K A) := + λ f1 f2, ∀ k, f1 !! k ⊑ f2 !! k. + +Instance gmap_PreOrder `{Countable K} `{Extension A} `{PreOrder A (⊑)} : @PreOrder (gmap K A) (⊑). +Proof. + econstructor. + - move => ? ?; reflexivity. + - move => ? ? ? ? ? ?. by etransitivity. +Qed. +Instance gmap_PartialOrder `{Countable K} `{Extension A} `{PartialOrder A (⊑)} : @PartialOrder (gmap K A) (⊑). +Proof. + econstructor. + - by eauto with typeclass_instances. + - move => ? ? ? ?. apply: map_eq => k. by apply: anti_symm. +Qed. + +Instance gmap_JSL `{Countable K} `{JoinSemiLattice A} : JoinSemiLattice (gmap K A). +Proof. + econstructor. + - exact: gmap_PreOrder. + - move => ? ? ?. rewrite lookup_join. by apply join_ext_l. + - move => ? ? ?. rewrite lookup_join. by apply join_ext_r. + - move => ? ? ? ? ? ?. rewrite lookup_join. by apply join_least. +Qed. + +(* unit instances *) +Instance unit_Extension : Extension () := + λ u1 u2, True. +Instance unit_Join : Join () := + λ u1 u2, tt. +Instance unit_PreOrder : @PreOrder () (⊑). +Proof. econstructor; by auto. Qed. +Instance unit_JSL : JoinSemiLattice (). +Proof. econstructor; first exact: unit_PreOrder; by auto. Qed. + +(* gset instances *) +Instance gset_Extension `{Countable K} : Extension (gset K) := + λ s1 s2, ∀ k, k ∈ s1 → k ∈ s2. +Instance gset_Join `{Countable K} : Join (gset K) := + λ s1 s2, Mapset (join (A:=gmap K ()) (mapset_car s1) (mapset_car s2)). +Instance gset_PreOrder `{Countable K} : @PreOrder (gset K) (extension). +Proof. + econstructor. + - by move => ? ? //. + - move => ? ? ? ? ? ?. by eauto. +Qed. +Instance gset_PartialOrder `{Countable K} : @PartialOrder (gset K) (extension). +Proof. + econstructor. + - by eauto with typeclass_instances. + - move => ? ? H1 H2. apply/mapset_eq => ?. split; by [move/H1|move/H2]. +Qed. +Instance gset_JSL `{Countable K} : JoinSemiLattice (gset K). +Proof. + econstructor. + - exact: gset_PreOrder. + - move => ? ? ? In. do 2!red. rewrite lookup_join. rewrite In. by case: (_ !! _) => //. + - move => ? ? ? In. do 2!red. rewrite lookup_join. rewrite In. by case: (_ !! _) => //. + - move => ? ? ? H1 H2 k. + move: (H1 k) (H2 k). + unfold elem_of, mapset_elem_of. + rewrite lookup_join. by repeat case : (_ !! _) => [[]|] //. +Qed. + +Lemma gset_Assoc `{Countable K} : @Assoc (gset K) (=) join. +Proof. move => ? ? ?. by rewrite /join /gset_Join gmap_Assoc. Qed. + +Lemma elem_of_join `{Countable K} (s1 s2 : gset K) (k : K) : k ∈ (join s1 s2) ↔ k ∈ s1 ∨ k ∈ s2. +Proof. + unfold elem_of, mapset_elem_of. cbn. + unfold join, gmap_Join. + rewrite lookup_union_with. + repeat case: (_ !! k) => [[]|]; tauto. +Qed. + +Lemma elem_of_extension `{Countable K} (X Y : gset K) : X ⊑ Y ↔ (∀ x : K, x ∈ X → x ∈ Y). +Proof. tauto. Qed. \ No newline at end of file diff --git a/coq/ra/machine.v b/coq/ra/machine.v index f2acc194e0113bd76deea56e6b22bb64d945bb79..641b2e65ff797b445e7466ba66f4e4a07e737d4e 100644 --- a/coq/ra/machine.v +++ b/coq/ra/machine.v @@ -1,6 +1,6 @@ From mathcomp Require Import ssreflect ssrbool seq. -From iris.prelude Require Export strings list numbers. -From iris.prelude Require Export gmap finite co_pset mapset. +From iris.prelude Require Export strings list numbers sorting. +From iris.prelude Require Export gmap finite mapset. Global Generalizable All Variables. Global Set Automatic Coercions Import. @@ -10,6 +10,8 @@ From Coq Require Export Utf8. Open Scope positive. +From ra Require Export infrastructure. + Reserved Notation "'<' x → v @ t , R >" (at level 20, format "< x → v @ t , R >", x at level 21, v at level 21, t at level 21, R at level 21). @@ -17,17 +19,6 @@ Reserved Notation "'<' x → v @ t , R >" (at level 20, format "< x → v @ t , Section RAMachine. Context `{Countable Loc} `{Countable Val0}. - Section Infrastructure. - Instance injective_dec_eq - `{H : ∀ x y : A, Decision (x = y)} {B : Type} - f (g : A -> option B) (Inj : ∀ x, g (f x) = Some x) : ∀ x y : B, Decision (x = y) | 1000. - Proof. - move => x y. case: (decide (f x = f y)). - - move/(f_equal g). rewrite !Inj => [[]]. by left. - - move => NEq. right => Eq. apply: NEq. by rewrite Eq. - Qed. - End Infrastructure. - Inductive Val := | A | D | VInj (v : Val0). (* Definition isval : _ -> Prop := λ v, match v with V _ => True | _ => False end. *) @@ -48,53 +39,6 @@ Section RAMachine. }. Global Arguments mkMessage _ _ _%positive _. - - Global Instance Time_SubsetEq : SubsetEq Time := Pos.le. - Global Instance Time_Union : Union Time := Pos.max. - Global Instance Time_SubsteqAntiSymm : AntiSymm (=) (Time_SubsetEq) := Pos.le_antisym. - Global Instance Time_JoinSemiLattice : JoinSemiLattice Time. - Proof. - split. - - by auto with typeclass_instances. - - by firstorder using Pos.le_max_l. - - by firstorder using Pos.le_max_r. - - move => t1 t2 t3 H13 H23. by apply/Pos.max_lub_iff. - Qed. - - Global Existing Instance option_union | 1000. - Global Instance opt_le_union `{Union T} : Union (option T) | 0 := - λ o1 o2, match o1 with | Some x => Some match o2 with Some y => (x ∪ y) | None => x end | None => o2 end. - Global Instance opt_le_SubsetEq `{SubsetEq T} : SubsetEq (option T) := - λ o1 o2, match o1, o2 with | Some x, Some y => x ⊆ y | None, _ => True | Some _, _ => False end. - Global Instance opt_le_PreOrder `{S : SubsetEq T} `{PreOrder _ S} : PreOrder (opt_le_SubsetEq). - Proof. - split. - - move => [x|]; cbn; reflexivity. - - move => [x|] [y|] [z|]; cbn; first (by transitivity y); tauto. - Qed. - Global Instance opt_le_AntiSymm `{S : SubsetEq T} `{AntiSymm T (=) S} : AntiSymm (=) opt_le_SubsetEq. - Proof. - move => [?|] [?|] //= S1 S2. f_equal. by apply H3. - Qed. - - Lemma option_subseteq_is_Some `{SubsetEq T} (o1 o2 : option T) : o1 ⊆ o2 -> is_Some o1 -> is_Some o2. - Proof. - unfold subseteq, opt_le_SubsetEq. (repeat case_match). - - by eauto. - - by eauto. - - by move => _ [] //. - Qed. - - Global Instance opt_le_JoinSemiLattice `{JoinSemiLattice T} : JoinSemiLattice (option T). - Proof. - split. - - exact: opt_le_PreOrder. - - move => [x|] [y|]; cbn; first (apply: union_subseteq_l); by auto. - - move => [x|] [y|]; cbn; first (apply: union_subseteq_r); by auto. - - move => [x|] [y|] [z|]; cbn; first (apply: union_least); by auto. - Qed. - - Definition message_tuple : Type := Loc * (Val * (Time * View)). Definition msg_to_tuple (m : message) : message_tuple := (m.(loc), (m.(val), (m.(time), m.(view)))). Definition tuple_to_msg (m : message_tuple) : message := @@ -102,26 +46,6 @@ Section RAMachine. | (l, (v, (t, R))) => mkMessage l v t R end. - Global Instance View_countable : Countable View := - injective_countable (map_to_list : View -> list (Loc * Time)) - ((λ l : list (Loc * Time), Some (map_of_list l)) : list _ -> option View) _. - Proof. - intros. f_equal. exact: map_of_to_list. - Qed. - - Global Instance View_SubsetEq : SubsetEq View := λ X Y, ∀ x, @subseteq _ opt_le_SubsetEq (X !! x) (Y !! x). - Global Instance View_PreOrder : PreOrder View_SubsetEq. - Proof. - split. - - move => X x. reflexivity. - - move => X Y Z HXY HYZ x. by transitivity (Y !! x). - Qed. - Global Instance View_SubsetEq_AntiSym `{AntiSymm (option Time) (=) (subseteq)} : AntiSymm (=) View_SubsetEq. - Proof. - move => ? ? S1 S2. apply: map_eq => x. - by apply: anti_symm. - Qed. - Definition val_to_sum : Val -> _ := λ v, match v with | A => inl () | D => inr (inl ()) | VInj v => inr (inr v) end. Definition sum_to_val : _ -> Val := λ s, match s with | inl () => A | inr (inl ()) => D | inr (inr v) => VInj v end. Global Instance Val_dec_eq : ∀ v1 v2 : Val, Decision (v1 = v2) := @@ -143,33 +67,6 @@ Section RAMachine. Global Instance message_dec_eq : ∀ (m1 m2 : message), Decision (m1 = m2) := _. Global Instance message_countable : Countable message := _. - - Global Instance View_Union : Union View := union_with (λ t1 t2, Some (t1 ∪ t2)). - - Global Instance View_JoinSemiLattice : JoinSemiLattice View | 0. - Proof. - split. - - by auto with typeclass_instances. - - move => X Y x. - rewrite lookup_union_with. - case : (X !! x) => [tX|]; case : (Y !! x) => [tY|]; cbn. - + apply union_subseteq_l. - + reflexivity. - + reflexivity. - + tauto. - - move => X Y x. - rewrite lookup_union_with. - case : (X !! x) => [tX|]; case : (Y !! x) => [tY|]; cbn. - + apply union_subseteq_r. - + reflexivity. - + reflexivity. - + tauto. - - move => X Y Z HXY HYZ x. move: (HXY x) (HYZ x). - rewrite lookup_union_with. - case : (X !! x) => [tX|]; case : (Y !! x) => [tY|]; case : (Z !! x) => [tZ|]; cbn; try tauto. - apply union_least. - Qed. - End Definitions. @@ -222,22 +119,11 @@ Section RAMachine. x at level 21, v at level 21, t at level 21, R at level 21). Section Machine. - - Definition msg_disj m m' := m.(loc) ≠m'.(loc) ∨ m.(time) ≠m.(time). Lemma msg_disj_symm m1 m2 : msg_disj m1 m2 -> msg_disj m2 m1. Proof. now firstorder. Qed. - Existing Instance message_dec_eq. - Existing Instance message_countable. Notation MessageSet := (gset message). - Existing Instance mapset_elem_of. - Existing Instance mapset_empty. - Existing Instance mapset_union. - Existing Instance mapset_intersection. - Existing Instance mapset_singleton. - - Global Instance MessageSet_JoinSemiLattice : JoinSemiLattice MessageSet := _. Definition MS_disj (M M' : MessageSet) := ∀ m m', m ∈ M -> m' ∈ M' -> msg_disj m m'. @@ -246,25 +132,88 @@ Section RAMachine. Definition pairwise_disj (M : MessageSet) := ∀ m m', m ∈ M -> m' ∈ M -> m = m' ∨ msg_disj m m'. Definition view_ok (M : MessageSet) V := - ∀ x t, V !! x = Some t → ∃ m, m ∈ M ∧ m.(loc) = x ∧ m.(time) = t ∧ m.(view) ⊆ V. + ∀ x t, V !! x = Some t → ∃ m, m ∈ M ∧ m.(loc) = x ∧ m.(time) = t ∧ m.(view) ⊑ V. Definition timemap_ok (M : MessageSet) (T : timemap) := ∀ x t, T !! x = Some t → ∃ m, m ∈ M ∧ m.(loc) = x ∧ m.(time) = t. Definition timemap_complete (M : MessageSet) (T : timemap) := ∀ m, m ∈ M → is_Some (T !! m.(loc)). - Inductive MaxTime (M : MessageSet) (x : Loc) : option Time -> Prop := + Inductive MaxTime (M : MessageSet) (x : Loc) : option Time -> Type := | MT_None (NoEl : ∀ m, m ∈ M -> m.(loc) = x -> False) : MaxTime M x None | MT_Some t v R (El : <x → v@t, R> ∈ M) (Le : ∀ m, m ∈ M -> m.(loc) = x -> m.(time) ≤ t) : MaxTime M x (Some t) . + Definition MT_nomsg `(Max : MaxTime M x None) : ∀ m, m ∈ M -> m.(loc) = x -> False := + match Max with + | MT_None NoEl => NoEl + end. + + Definition MT_msg `(Max : MaxTime M x (Some t)) : message := + <x → + match Max with MT_Some _ v _ _ _ => v end + @ t, match Max with MT_Some t v R _ _ => R end >. + + Definition MT_msg_loc `(Max : MaxTime M x (Some t)) : loc (MT_msg Max) = x := eq_refl. + + Definition MT_msg_time `(Max : MaxTime M x (Some t)) : time (MT_msg Max) = t := eq_refl. + + Definition MT_msg_In `(Max : MaxTime M x (Some t)) : MT_msg Max ∈ M := + match Max as Max' in MaxTime _ _ ot return + match ot as ot' return MaxTime _ _ ot' -> Prop with + | None => λ _, True + | Some t => λ MT, MT_msg MT ∈ M + end Max' + with + | MT_None _ => I + | MT_Some t v R EL _ => EL + end. + + Hint Extern 0 (loc (MT_msg _)) => apply MT_msg_loc. + Hint Extern 0 (time (MT_msg _)) => apply MT_msg_time. + Hint Extern 0 ((@MT_msg ?M _ _ _) ∈ ?M) => apply MT_msg_In. + Definition MT_msg_In_unf `(Max : MaxTime M x (Some t)) : + <loc (MT_msg Max) → val (MT_msg Max) @ time (MT_msg Max) , view (MT_msg Max)> ∈ M := + match Max as Max' in MaxTime _ _ ot return + match ot as ot' return MaxTime _ _ ot' -> Prop with + | None => λ _, True + | Some t => λ Max, + <loc (MT_msg Max) → val (MT_msg Max) @ time (MT_msg Max) , view (MT_msg Max)> ∈ M + end Max' + with + | MT_None _ => I + | MT_Some t v R EL _ => EL + end. + + Definition MT_msg_max `(Max : MaxTime M x (Some t)) : + ∀ m, m ∈ M -> loc m = x -> time m ≤ time (MT_msg Max) := + match Max as Max' in MaxTime _ _ ot return + match ot as ot' return MaxTime _ _ ot' -> Prop with + | None => λ _, True + | Some t => λ MT, + ∀ m, m ∈ M -> loc m = x -> time m ≤ time (MT_msg MT) + end Max' + with + | MT_None _ => I + | MT_Some t v R _ LE => LE + end. + Lemma MaxTime_Some_Lt {M x t} : MaxTime M x (Some t) -> ∀ m, m ∈ M -> m.(loc) = x -> m.(time) ≤ t. Proof. by inversion 1. Qed. + Definition MT_fun `(Max1 : MaxTime M x ot1) `(Max2 : MaxTime M x ot2) : ot1 = ot2. + Proof. + destruct ot1 as [t1|], ot2 as [t2|] => //; + rewrite -?(MT_msg_time Max1) -?(MT_msg_time Max2). + - f_equal. apply: anti_symm; by apply: MT_msg_max. + - exfalso. by apply: (MT_nomsg Max2); first exact: MT_msg_In. + - exfalso. by apply: (MT_nomsg Max1); first exact: MT_msg_In. + Qed. + Instance MessageSet_Filter : Filter message MessageSet := λ P EqDec M, of_list (filter P (elements M)). @@ -273,47 +222,47 @@ Section RAMachine. by rewrite !elem_of_of_list !elem_of_list_filter elem_of_elements. Qed. - Lemma MS_filter_union {M1 M2 : MessageSet} `{DecP : ∀ m, Decision (P m)} : - filter P (M1 ∪ M2) = filter P M1 ∪ filter P M2. + Lemma MS_filter_join {M1 M2 : MessageSet} `{DecP : ∀ m, Decision (P m)} : + filter P (M1 ⊔ M2) = filter P M1 ⊔ filter P M2. Proof. apply mapset_eq => m. - rewrite elem_of_union !elem_of_MS_filter elem_of_union. + rewrite elem_of_join !elem_of_MS_filter elem_of_join. tauto. Qed. - Lemma MaxTime_pred_mono `{∀ m, Decision (P1 m)} `{∀ m, Decision (P2 m)} {M x ot1 ot2} : MaxTime (filter P1 M) x ot1 -> MaxTime (filter P2 M) x ot2 -> (∀ m, P1 m -> P2 m) -> ot1 ⊆ ot2. + Lemma MaxTime_pred_mono `{∀ m, Decision (P1 m)} `{∀ m, Decision (P2 m)} {M x ot1 ot2} : MaxTime (filter P1 M) x ot1 -> MaxTime (filter P2 M) x ot2 -> (∀ m, P1 m -> P2 m) -> ot1 ⊑ ot2. Proof. - (* inversion 1; inversion 1 => HP; subst. *) - (* - reflexivity. *) - (* - reflexivity. *) - (* - exfalso. *) - (* apply: NoEl. first apply HP. first eassumption; first by []. exact: HP. *) - (* - cbn. destruct El as (? & ? & In & ?). *) - (* apply: (Le0 _ In eq_refl). exact: HP. *) - (* Qed. *) - Admitted. + case ot1, ot2 => MT1 MT2 HP //. + - rewrite -(MT_msg_time MT1) -(MT_msg_time MT2). + apply: MT_msg_max; last exact: MT_msg_loc. + apply/elem_of_MS_filter. move/elem_of_MS_filter : (MT_msg_In MT1) => []; split; by eauto. + - exfalso. apply: (MT_nomsg MT2); last exact: MT_msg_loc. + + apply/elem_of_MS_filter. case/elem_of_MS_filter : (MT_msg_In MT1). by auto. + Qed. Lemma MaxTime_set_mono {M1 M2 x ot1 ot2} : - MaxTime M1 x ot1 -> MaxTime M2 x ot2 -> MaxTime (M1 ∪ M2) x (ot1 ∪ ot2). + MaxTime M1 x ot1 -> MaxTime M2 x ot2 -> MaxTime (M1 ⊔ M2) x (ot1 ⊔ ot2). Proof. - inversion 1; inversion 1; subst. - - constructor => m /elem_of_union []; by firstorder. - - econstructor. - + apply/elem_of_union; right; eassumption. - + move => m /elem_of_union [/NoEl|/Le]; by intuition. - - econstructor. - + apply/elem_of_union; left; eassumption. - + move => m /elem_of_union [/Le|/NoEl]; by intuition. - - assert (Dec : {t ∪ t0 = t} + {t ∪ t0 = t0}). - { exact: Pos.max_dec. } - assert (LT' : ∀ m : message, m ∈ M1 ∪ M2 → loc m = x → time m ≤ t ∪ t0). - { move => ? /elem_of_union [/Le|/Le0] EqLoc. - - transitivity t; last exact: Pos.le_max_l; exact: EqLoc. - - transitivity t0; last exact: Pos.le_max_r; exact: EqLoc. + move: ot1 ot2 => [t1|] [t2|] MT1 MT2; cbn. + rewrite -?(MT_msg_time MT1) -?(MT_msg_time MT2); cbn. + - assert (Dec : {join t1 t2 = t1} + {join t1 t2 = t2}) by exact: Pos.max_dec. + pose (m := if Dec then MT_msg MT1 else MT_msg MT2). + assert (if Dec then t2 ⊑ t1 else t1 ⊑ t2). + { destruct Dec as [Eq|Eq]; rewrite /= -Eq. by apply join_ext_r. by apply join_ext_l. } + assert (∀ m', m' ∈ M1 ⊔ M2 -> loc m' = x -> time m' ≤ time m). + { destruct Dec; simpl in *; unfold m; + (move => ? /elem_of_join [|] In EqLoc; + [move : (MT_msg_max MT1 _ In EqLoc)|move : (MT_msg_max MT2 _ In EqLoc)]); + by eauto using Pos.le_trans. } - + case: Dec => [Dec|Dec]; (econstructor => //; rewrite Dec; apply/elem_of_union). - * left. eassumption. - * right. eassumption. + destruct Dec as [Eq|Eq]; cbn in *; rewrite Eq; + econstructor => //; + apply/elem_of_join; [left|right]; exact: MT_msg_In. + - econstructor; first (apply/elem_of_join; left; exact: MT_msg_In). + move => ? /elem_of_join [|/(MT_nomsg MT2) //] ? ?. exact: MT_msg_max. + - econstructor; first (apply/elem_of_join; right; exact: MT_msg_In). + move => ? /elem_of_join [/(MT_nomsg MT1) //|] ? ?. exact: MT_msg_max. + - econstructor. move => ? /elem_of_join [|] /MT_nomsg; by eauto. Qed. Record memory := @@ -321,15 +270,15 @@ Section RAMachine. msgs :> MessageSet; _ : pairwise_disj msgs }. - Implicit Type (M : memory). + Definition memory_ok : ∀ M, pairwise_disj M.(msgs) := ltac:(by destruct 0). Program Definition add_ins (M : memory) m : MS_msg_disj M m -> memory := - fun H => mkMemory (union (msgs M) (singleton m)) _. + fun H => mkMemory (join (msgs M) (singleton m)) _. Next Obligation. intros M m ? m1 m2. - move => /elem_of_union [El1|/elem_of_singleton Eq1]; - move => /elem_of_union [El2|/elem_of_singleton Eq2]. + move => /elem_of_join [El1|/elem_of_singleton Eq1]; + move => /elem_of_join [El2|/elem_of_singleton Eq2]. - case: (memory_ok _ _ _ El1 El2); by [left | right]. - rewrite -> Eq2. right. apply: msg_disj_symm. exact: H3. - rewrite -> Eq1. right; exact: H3. @@ -337,12 +286,12 @@ Section RAMachine. Qed. Lemma MaxTime_add_ins_old (M M2 : MessageSet) x ot (NEq : ∀ m, m ∈ M2 → x ≠m.(loc)) : - MaxTime M x ot -> MaxTime (M ∪ M2) x ot. + MaxTime M x ot -> MaxTime (M ⊔ M2) x ot. Proof. - inversion 1; econstructor. - - move => ? /elem_of_union [/NoEl //|In ?]. exact: NEq. - - apply/elem_of_union; left; eauto. - - move => ? /elem_of_union [/Le //|In ?]. exfalso; exact: NEq. + case: ot => [t|] => MT1; econstructor. + - apply/elem_of_join. left; by apply: (MT_msg_In MT1). + - move => ? /elem_of_join [/(MT_msg_max MT1)|/NEq NEq' ?]; first auto. by destruct NEq'. + - move => ? /elem_of_join [/(MT_nomsg MT1)|/NEq NEq' ?]; first tauto. by destruct NEq'. Qed. (* Instance View_Singleton : Singleton (Loc * Time) View := λ xt, <[xt.1 := xt.2]> empty. *) @@ -352,17 +301,17 @@ Section RAMachine. | Th_Read m acc (InM : m ∈ msgs M) (Lt : ∀ t', V !! m.(loc) = Some t' -> (t' ≤ m.(time))) (* TODO: must not be None! *) - : thread_red V M (ERead acc m.(loc) m.(val)) (V ∪ m.(view)) M + : thread_red V M (ERead acc m.(loc) m.(val)) (V ⊔ m.(view)) M | Th_Write x v t V' m acc (Lt : ∀ t', V !! x = Some t' -> (t' < t)) (* TODO: must not be None! *) - (EV' : V' = V ∪ {[x := t]}) + (EV' : V' = V ⊔ {[x := t]}) (Em : m = < x → v @ t, V' >) (Disj : MS_msg_disj M m) : thread_red V M (EWrite acc x v) V' (add_ins M m Disj) | Th_Update x v_r t R V' m v_w (InM : <x→v_r@t, R> ∈ msgs M) (Lt : ∀ t', V !! x = Some t' -> (t' ≤ t)) (* TODO: must not be None! *) - (EV' : V' = V ∪ {[x := t+1]} ∪ R) + (EV' : V' = V ⊔ {[x := t+1]} ⊔ R) (Em : m = < x → v_w @ t + 1, V' >) (Disj : MS_msg_disj M m) : thread_red V M (EUpdate x v_r v_w) V' (add_ins M m Disj) @@ -379,21 +328,21 @@ Section RAMachine. Definition msgs_ok M := ∀ m, m ∈ msgs M → msg_ok m ∧ view_ok (msgs M) m.(view). Definition threads_ok σ := ∀ Ï€ V, threads σ !! Ï€ = Some V → view_ok (mem σ) V. - Definition view_mono V V' := ∀ x, V !! x ⊆ V' !! x. + Definition view_mono V V' := V ⊑ V'. Definition thread_inv (V : View) (M : memory) := msgs_ok M ∧ view_ok M V. - Definition msgs_mono M M' := msgs M ⊆ msgs M'. + Definition msgs_mono M M' := msgs M ⊑ msgs M'. Section ThreadReduction. - Lemma view_ok_mono : Proper ((⊆) ==> (=) ==> impl) view_ok. + Lemma view_ok_mono : Proper ((⊑) ==> (=) ==> impl) view_ok. Proof. - move => M1 M2 /elem_of_subseteq HM V1 V2 <- {V2} VOk x t HVt2. + move => M1 M2 /elem_of_extension HM V1 V2 <- {V2} VOk x t HVt2. edestruct (VOk) as (m & A & B & C & D); first eassumption. exists m; repeat split; by auto. Qed. - Lemma lookup_union (X Y : View) x ot : (X ∪ Y) !! x = ot → X !! x = ot ∨ Y !! x = ot. + Lemma lookup_join (X Y : View) x ot : (X ⊔ Y) !! x = ot → X !! x = ot ∨ Y !! x = ot. Proof. rewrite lookup_union_with. case : (X !! x) => [tX|]; @@ -402,56 +351,55 @@ Section RAMachine. - left. f_equal. by symmetry. - right. f_equal. by symmetry. Qed. - - Lemma lookup_union_max (X Y : View) x : (X ∪ Y) !! x = X !! x ∪ Y !! x. + Lemma lookup_join_max (X Y : View) x : (X ⊔ Y) !! x = X !! x ⊔ Y !! x. Proof. rewrite lookup_union_with. case : (X !! x) => [tX|]; case : (Y !! x) => [tY|]; cbn; by auto. Qed. - Lemma view_union_assoc V R S : V ∪ (R ∪ S) = (V ∪ R) ∪ S. + Lemma view_join_assoc V R S : V ⊔ (R ⊔ S) = (V ⊔ R) ⊔ S. Proof. apply: map_eq => x. rewrite !lookup_union_with. repeat case : (_ !! x) => [?|]; cbn; try auto. - unfold union, Time_Union. by rewrite Pos.max_assoc. + f_equal. exact: Pos.max_assoc. Qed. Lemma msg_ok_write V (x : Loc) v t (Lt : ∀ t' : Time, V !! x = Some t' → t' < t) - : msg_ok (<x→v@t,(V ∪ {[x := t]})>). + : msg_ok (<x→v@t,(V ⊔ {[x := t]})>). Proof. - cbv [msg_ok] => /=. rewrite lookup_union_max lookup_singleton. + cbv [msg_ok] => /=. rewrite lookup_join_max lookup_singleton. case HVx : (V !! _) => [?|] //=. move/Lt : HVx => HVx; cbn. f_equal. - apply: (anti_symm (⊆)). - - apply union_least; last reflexivity. + apply: (anti_symm). + - apply join_least; last reflexivity. exact: Pos.lt_le_incl. - - by apply union_subseteq_r. + - by apply join_ext_r. Qed. - Lemma view_ok_write M V x v t + Lemma view_ok_write (M : memory) V x v t (VOk : view_ok M V) - (Disj : MS_msg_disj M (<x→v@t,(V ∪ {[x := t]})>)) : - view_ok (add_ins M (<x→v@t,(V ∪ {[x := t]})>) Disj) - (view (<x→v@t,(V ∪ {[x := t]})>)). + (Disj : MS_msg_disj M (<x→v@t,(V ⊔ {[x := t]})>)) : + view_ok (add_ins M (<x→v@t,(V ⊔ {[x := t]})>) Disj) + (view (<x→v@t,(V ⊔ {[x := t]})>)). Proof. - move => z tz /lookup_union [/VOk|/lookup_singleton_Some [<- <-]]. + move => z tz /lookup_join [/VOk|/lookup_singleton_Some [<- <-]]. - move => [[y vy ty Ry] /= [Hm1 [Hm2 [Hm3 Hm4]]]]; subst. exists (<z → vy @ tz, Ry>) => /=. repeat (split; first try (reflexivity || eassumption)). - + apply elem_of_union; by left. - + transitivity V; first assumption. by apply union_subseteq_l. + + apply elem_of_join; by left. + + transitivity V; first assumption. by apply join_ext_l. - eexists; repeat split; - first (apply/elem_of_union; right; by apply elem_of_singleton); by auto. + first (apply/elem_of_join; right; by apply elem_of_singleton); by auto. Qed. Lemma msg_ok_update M V R x v_r v_w t (MOk : msg_ok (<x→v_r@t,R>)) (InM : <x→v_r@t,R> ∈ msgs M) (Lt : ∀ t' : Time, V !! x = Some t' → t' ≤ t) - : msg_ok (<x→v_w@(t + 1),(V ∪ {[x := t + 1]} ∪ R)>). + : msg_ok (<x→v_w@(t + 1),(V ⊔ {[x := t + 1]} ⊔ R)>). Proof with eauto using Pos.lt_add_diag_r, Pos.lt_le_incl. - cbv [msg_ok] => /=. rewrite !lookup_union_max lookup_singleton MOk. + cbv [msg_ok] => /=. rewrite !lookup_join_max lookup_singleton MOk. case HVx : (V !! _) => [?|] //=. - move/Lt : HVx => HVx; cbn. f_equal. apply: Pos.le_antisym. @@ -459,7 +407,7 @@ Section RAMachine. * transitivity t... * reflexivity. * trivial ... - + rewrite (_ : _ ∪ (t + 1) = t + 1); first rewrite (_ : t + 1 ∪ t = t + 1). + + rewrite (_ : _ ⊔ (t + 1) = t + 1); first rewrite (_ : t + 1 ⊔ t = t + 1). * reflexivity. * apply/Pos.max_l_iff... * apply/Pos.max_r_iff. transitivity t... @@ -470,32 +418,32 @@ Section RAMachine. (InM : <x→v_r@t,R> ∈ msgs M) (VOk : view_ok M V) (ROk : view_ok M R) - (Disj : MS_msg_disj M (<x→v_w@(t + 1),(V ∪ {[x := t + 1]} ∪ R)>)) : - view_ok (add_ins M (<x→v_w@(t + 1),(V ∪ {[x := t + 1]} ∪ R)>) Disj) - (view (<x→v_w@(t + 1),(V ∪ {[x := t + 1]} ∪ R)>)). + (Disj : MS_msg_disj M (<x→v_w@(t + 1),(V ⊔ {[x := t + 1]} ⊔ R)>)) : + view_ok (add_ins M (<x→v_w@(t + 1),(V ⊔ {[x := t + 1]} ⊔ R)>) Disj) + (view (<x→v_w@(t + 1),(V ⊔ {[x := t + 1]} ⊔ R)>)). Proof. - move => z tz /lookup_union [/lookup_union [/VOk|/lookup_singleton_Some [<- <-]]|/ROk]. + move => z tz /lookup_join [/lookup_join [/VOk|/lookup_singleton_Some [<- <-]]|/ROk]. - move => [[y vy ty Ry] /= [Hm1 [Hm2 [Hm3 Hm4]]]]; subst. exists (<z → vy @ tz, Ry>) => /=. repeat (split; first try (reflexivity || eassumption)). - + apply elem_of_union; by left. - + transitivity V; first assumption. rewrite -assoc. by apply union_subseteq_l. + + apply elem_of_join; by left. + + transitivity V; first assumption. rewrite -assoc. by apply join_ext_l. - eexists; repeat split; - first (apply/elem_of_union; right; by apply elem_of_singleton); by auto. + first (apply/elem_of_join; right; by apply elem_of_singleton); by auto. - move => [[y vy ty Ry] /= [Hm1 [Hm2 [Hm3 Hm4]]]]; subst. exists (<z → vy @ tz, Ry>) => /=. repeat (split; first try (reflexivity || eassumption)). - + apply elem_of_union; by left. - + transitivity R; first assumption. by apply union_subseteq_r. + + apply elem_of_join; by left. + + transitivity R; first assumption. by apply join_ext_r. Qed. Lemma msgs_ok_add_ins x v t M V m' R (MOk : msgs_ok M) (VOk : view_ok M V) - (Disj : MS_msg_disj M (<x→v@t,(V ∪ R)>)): + (Disj : MS_msg_disj M (<x→v@t,(V ⊔ R)>)): m' ∈ msgs M → msg_ok m' ∧ view_ok (add_ins M _ Disj) (view m'). Proof. move/MOk => []; split; first by auto. apply: view_ok_mono; last by eassumption. - { by eapply union_subseteq_l. } + { by eapply join_ext_l. } { reflexivity. } Qed. @@ -506,31 +454,31 @@ Section RAMachine. induction 1; subst. - split; first assumption. move => y ty Hyty. - case/lookup_union: Hyty. + case/lookup_join: Hyty. + move/VOk => [[? vy ? Ry] /= [Hm1 [Hm2 [Hm3 Hm4]]]]; subst. exists (<y → vy @ ty, Ry>) => /=. repeat (split; first (reflexivity || eassumption)). transitivity V; first assumption. - now apply union_subseteq_l. + now apply join_ext_l. + move/MOk : InM => [_] ROk /ROk [[? vy ? Ry] /= [Hm1 [Hm2 [Hm3 Hm4]]]]; subst. exists (<y → vy @ ty, Ry>) => /=. repeat (split; first (reflexivity || eassumption)). transitivity (view m); first assumption. - now apply union_subseteq_r. + now apply join_ext_r. - split. - + move => m' /elem_of_union [|/elem_of_singleton ->]. + + move => m' /elem_of_join [|/elem_of_singleton ->]. * exact: msgs_ok_add_ins. * split; [exact: msg_ok_write|exact: view_ok_write]. + exact: view_ok_write. - case: (MOk _ InM) => [? ?]. split. - + move => m' /elem_of_union [|/elem_of_singleton ->]. - * rewrite -view_union_assoc. exact: msgs_ok_add_ins. + + move => m' /elem_of_join [|/elem_of_singleton ->]. + * rewrite -view_join_assoc. exact: msgs_ok_add_ins. * split; [exact: msg_ok_update|exact: view_ok_update]. + exact: view_ok_update. Qed. - Lemma add_ins_mono M m Disj : msgs M ⊆ msgs (add_ins M m Disj). + Lemma add_ins_mono M m Disj : msgs M ⊑ msgs (add_ins M m Disj). Proof. - move => ? ?. apply/elem_of_union. by left. + move => ? ?. apply/elem_of_join. by left. Qed. Lemma thread_red_msgs_mono V M evt V' M' : thread_red V M evt V' M' -> msgs_mono M M'. @@ -543,39 +491,19 @@ Section RAMachine. Lemma thread_red_view_mono V M evt V' M' : thread_inv V M -> thread_red V M evt V' M' -> view_mono V V'. Proof. - move => ThrdInv. inversion 1; subst. - - unfold view_mono. - move => y. - rewrite lookup_union_with. - case: (V !! y) => [t1|] //. - case: (view m !! y) => [t2|] //. - cbn. by apply union_subseteq_l. - - move => y. - rewrite lookup_union_with. - case: (V !! y) => [t1|] //. - case: (decide (x = y)) => [<-|?]. - + rewrite lookup_singleton. - cbn. by apply union_subseteq_l. - + by rewrite lookup_singleton_ne. - - move => y. - rewrite !lookup_union_with. - case: (V !! y) => [t1|] //. - case: (R !! y) => [t2|]; - (case: (decide (x = y)) => [<-|?]; - first (rewrite lookup_singleton); last rewrite lookup_singleton_ne //). - * cbn. rewrite -assoc. by apply union_subseteq_l. - * cbn. by apply union_subseteq_l. - * cbn. by apply union_subseteq_l. + move => ThrdInv. inversion 1; subst; try by apply join_ext_l. + - red. rewrite -assoc. + by apply join_ext_l. Qed. End ThreadReduction. - Instance Lookup_opt_gmap `{Countable K} : Lookup K M (option (gmap K M)). - Proof. - move => M k [f|]. - - exact: (f !! k). - - exact: None. - Defined. + (* Instance Lookup_opt_gmap `{Countable K} : Lookup K M (option (gmap K M)). *) + (* Proof. *) + (* move => M k [f|]. *) + (* - exact: (f !! k). *) + (* - exact: None. *) + (* Defined. *) Section DataRaces. Inductive drf_red (σ σ' : state) (V : View) (x: Loc) : access -> Prop := @@ -583,7 +511,7 @@ Section RAMachine. (LV : V !! x = Some tl) (LNA : (nats σ) !! x = otna) (Hσ' : nats σ' = nats σ) - (GE : otna ⊆ Some tl) + (GE : otna ⊑ Some tl) : drf_red σ σ' V x at_hack | drf_na tl t' @@ -599,25 +527,25 @@ Section RAMachine. Definition nats_ok (M : MessageSet) nats := timemap_ok (M) (nats). Definition nats_complete (M : MessageSet) nats := timemap_complete M nats. - Lemma nats_ok_mono : Proper ((⊆) ==> (=) ==> impl) nats_ok. + Lemma nats_ok_mono : Proper ((⊑) ==> (=) ==> impl) nats_ok. Proof. move => M1 M2 /elem_of_subseteq HM V1 V2 <- {V2} NOk x t HVt2. edestruct NOk as (m & ? & ? & ?); first eassumption. exists m; repeat split; by auto. Qed. - Lemma nats_complete_mono : Proper ((=) ==> (⊆) ==> impl) nats_complete. + Lemma nats_complete_mono : Proper ((=) ==> (⊑) ==> impl) nats_complete. Proof. move => M1 M2 <- V1 V2 Subs NCom m /NCom [] t Hmt. - eapply option_subseteq_is_Some; by eauto. + eapply option_ext_is_Some; by eauto. Qed. - Lemma nats_complete_add_ins M m (D : MS_msg_disj M m) T : + Lemma nats_complete_add_ins (M : memory) m (D : MS_msg_disj M m) T : (∃ m', m' ∈ msgs M ∧ m'.(loc) = m.(loc)) -> nats_complete M T -> nats_complete (add_ins M _ D) T. Proof. move => [m' [In EqLoc]] NCom m'' /=. - move/elem_of_union => [/NCom //|/elem_of_singleton ->]. + move/elem_of_join => [/NCom //|/elem_of_singleton ->]. rewrite -EqLoc. exact: NCom. Qed. @@ -626,7 +554,7 @@ Section RAMachine. Lemma drf_red_safe σ σ' Ï€ x acc : msgs_mono (mem σ) (mem σ') -> drf_red σ σ' Ï€ x acc -> nats_ok (mem σ) (nats σ) -> nats_ok (mem σ') (nats σ'). Proof. move => Mono. inversion 1; subst; move => Inv y t. - - rewrite Hσ' => /Inv [? [? [? ?]]]. + - rewrite Hσ' => /Inv [? [? [? ?]]]; eexists; repeat split; first exact: Mono; by assumption. - rewrite Hσ'. rewrite lookup_insert_Some. move => [[Eq Eq']|[_ /Inv]]. @@ -641,23 +569,23 @@ Section RAMachine. Inductive allocated (M : MessageSet) x t : Prop := | is_allocated t_d t_a (TD : MaxTime (filter (λ m, (m.(val) = D)) M) x t_d) - (TA : MaxTime (filter (λ m, (m.(val) = D)) M) x (Some t_a)) - (Alloc : t_d ⊆ Some t_a) - (Local: t_a ≤ t). + (TA : MaxTime (filter (λ m, (m.(val) = A)) M) x (Some t_a)) + (Alloc : t_d ⊠Some t_a) + (Local: t_a ⊑ t). Inductive deallocated (M : MessageSet) x ot : Prop := | is_deallocated t_d t_a (TD : MaxTime (filter (λ m, (m.(val) = D)) M) x t_d) - (TA : MaxTime (filter (λ m, (m.(val) = D)) M) x t_a) - (DeAlloc : t_a ⊆ t_d) - (Local: t_d ⊆ ot). + (TA : MaxTime (filter (λ m, (m.(val) = A)) M) x t_a) + (DeAlloc : t_a ⊠t_d) + (Local: t_d ⊑ ot). Inductive initialized (M : MessageSet) x t : Prop := | is_initialized t_d t_a (TD : MaxTime (filter (λ m, (m.(val) = D)) M) x t_d) - (TA : MaxTime (filter (λ m, (m.(val) = D)) M) x (Some t_a)) - (Alloc : t_d ⊆ Some t_a) - (Local: t_a < t). + (TA : MaxTime (filter (λ m, (m.(val) = A)) M) x (Some t_a)) + (Alloc : t_d ⊠Some t_a) + (Local: t_a ⊠t). Inductive alloc_red (M : MessageSet) (V : View) (x : Loc) : event -> Prop := @@ -690,30 +618,33 @@ Section RAMachine. Lemma init_is_alloc M x t : initialized M x t -> allocated M x t. Proof. - inversion 1. econstructor; eauto. exact: Pos.lt_le_incl. + inversion 1. econstructor; [exact: TD|exact: TA| |] => //. + exact: Pos.lt_le_incl. Qed. - Lemma alloc_time_mono M m t : allocated M (m.(loc)) t -> t ≤ m.(time) -> allocated M (m.(loc)) (m.(time)). + Lemma alloc_time_mono M m t : allocated M (m.(loc)) t -> t ⊑ m.(time) -> allocated M (m.(loc)) (m.(time)). Proof. - inversion 1; intro; econstructor; eauto. etransitivity; eauto. + inversion 1. econstructor; [exact: TD|exact: TA| |] => //. + etransitivity; by eauto. Qed. Lemma alloc_add_ins_old (M : MessageSet) m x t (NEq : x ≠m.(loc)) : allocated M x t -> - allocated (M ∪ {[m]}) x t. + allocated (M ⊔ {[m]}) x t. Proof. inversion 1; econstructor; eauto. - - rewrite MS_filter_union. apply: MaxTime_add_ins_old => //. + - rewrite MS_filter_join. apply: MaxTime_add_ins_old => //. by move => ? /elem_of_MS_filter [? /elem_of_singleton ->]. - - rewrite MS_filter_union. apply: MaxTime_add_ins_old => //. + - rewrite MS_filter_join. apply: MaxTime_add_ins_old => //. by move => ? /elem_of_MS_filter [? /elem_of_singleton ->]. Qed. Lemma alloc_add_ins_new (M : MessageSet) m t (IsVal : m.(val) ≠D) (LE : t ≤ time m): allocated M (m.(loc)) t -> - allocated (M ∪ {[m]}) (m.(loc)) (m.(time)). + allocated (M ⊔ {[m]}) (m.(loc)) (m.(time)). Proof. - (* assert (HE : ∃ ot_a', ot_a' ⊆ Some (time m) ∧ MaxTime (λ m, val m = A) {[m]} (loc m) (ot_a')). *) + destruct m. + (* assert (HE : ∃ ot_a', ot_a' ⊑ Some (time m) ∧ MaxTime (λ m, val m = A) {[m]} (loc m) (ot_a')). *) (* { case: (decide (val m = A)) => ?. *) (* - exists (Some (time m)); split => //. *) (* econstructor. destruct m. *) @@ -734,16 +665,159 @@ Section RAMachine. (* apply Pos.max_lub_iff; split; last eassumption. *) (* by etransitivity; eauto. *) (* Qed. *) - Admitted. + Admitted. + + Definition rel_of {T X : Type} (f : T -> X) (r : relation X) : relation T := + λ (t1 t2 : T), r (f t1) (f t2). + Instance rel_of_Transitive : (@Transitive T r) → (@Transitive X (@rel_of X T f r)). + Proof. + repeat intro; unfold rel_of in *. + by eauto with typeclass_instances. + Qed. + Instance rel_of_Irreflexive : (@Irreflexive T r) → (@Irreflexive X (@rel_of X T f r)). + Proof. + repeat intro; unfold rel_of in *. + by eapply irreflexive_eq. + Qed. + + Definition of_loc (M : MessageSet) (x : Loc) : list message := + filter (λ m, loc m = x) (elements M). + Definition hist (M : MessageSet) (x : Loc) : list message := + merge_sort (rel_of time (⊑)) (of_loc M x). + + Definition hist_upto (M : MessageSet) (x : Loc) t : list message := + (fix f l := + match l with + | nil => nil + | m :: l => if decide(time m = t) then l else f l + end + ) (hist M x). + + Lemma hist_upto_suffix M x t : suffix_of (hist_upto M x t) (hist M x). + Proof. + unfold hist_upto. + generalize (hist M x). + induction l => //. + case_match. + - by eexists (_::nil). + - etransitivity; first eassumption. + by eexists (_::nil). + Qed. + + Lemma elem_of_contains (T : Type) (l1 l2 : list T) (t : T) : l2 `contains` l1 → t ∈ l2 → t ∈ l1. + Proof. + induction 1 => //. + - move/elem_of_cons => [->|?]; apply/elem_of_cons; tauto. + - move/elem_of_cons => [->|/elem_of_cons [->|?]]; apply/elem_of_cons. + + right; apply/elem_of_cons; tauto. + + by left. + + right; apply/elem_of_cons; tauto. + - move/IHcontains => ?. apply/elem_of_cons. tauto. + - by move/IHcontains1/IHcontains2. + Qed. + + Lemma elem_of_merge_sort {T : Type} {r} `{∀ x y : T, Decision (r x y)} (t : T) (l : list T) : t ∈ merge_sort r l ↔ t ∈ l. + Proof. + split; + apply: elem_of_contains; apply Permutation_contains. + - exact: merge_sort_Permutation. + - symmetry. exact: merge_sort_Permutation. + Qed. + + Lemma elem_of_hist (M : MessageSet) x m : m ∈ hist M x ↔ (loc m = x ∧ m ∈ M). + Proof. + rewrite elem_of_merge_sort /of_loc elem_of_list_filter. + intuition; by apply/elem_of_elements. + Qed. + + Lemma hist_complete {M : MessageSet} {x} {m} (In : m ∈ M) (EqLoc : loc m = x) : + m ∈ hist M x. + Proof. + by apply/elem_of_hist. + Qed. + + Lemma hist_exact (M : MessageSet) (disj : pairwise_disj M) x m (In : m ∈ M) (EqLoc : loc m = x) : suffix_of (m :: hist_upto M x (time m)) (hist M x). + Proof. + unfold hist_upto. + assert (NotNil : hist M x ≠nil). + { case HHist : (hist) => //. + exfalso. apply/elem_of_nil. rewrite -HHist. exact: hist_complete. + } + cut (StronglySorted (rel_of time (⊑)) (hist M x)); last first. + { apply StronglySorted_merge_sort. + cut (∀ m', m' ∈ M → loc m' = x → m' ∉ hist M x → time m < time m'); last first. + { by move => ? In' EqLoc' /(_ (hist_complete In' EqLoc')). } + cut (∀ m, m ∈ hist M x → loc m = x ∧ m ∈ M); last first. + { move => ? ?. exact/elem_of_hist. } + revert NotNil. + generalize (hist M x). + induction l => // NotNil Elem Prefix. + case: (decide _) => [?|?]. + case_match; simplify_eq. + - rewrite (_ : m = a) //. + destruct (disj m a) as [Eq|Disj]; eauto. + + apply: proj2. apply/Elem. apply/elem_of_cons. tauto. + + destruct Disj as [NEqLoc|NEqTime]; exfalso. + * apply: NEqLoc. symmetry. apply: proj1. apply/Elem. apply/elem_of_cons. tauto. + * by eauto. + - cbn. + destruct l. + + rewrite (_ : m = a) //. + case: (decide (m = a)) => // ?. + exfalso. apply: Pos.lt_irrefl. apply: Prefix => //. + apply/not_elem_of_cons; by eauto using not_elem_of_nil. + + etransitivity. apply: IHl => //. + * move => ? ?. apply/Elem. apply/elem_of_cons. tauto. + * move => m' ? ? ?. + case: (decide (m' = a)) => [?|?]; first subst. + apply: Prefix => //. apply/not_elem_of_cons; split => //. + * + + + + Definition AllocCond (hist : list message) (m : message) := + match val m with + | VInj v => ∃ m' hist', hist = m' :: hist' ∧ val m' ≠D + | A => ∀ m_d hist', hist = m_d :: hist' → val m_d = D + | D => ∀ m' hist', hist = m' :: hist' → val m' ≠D + end. + + Definition alloc_inv (M : MessageSet) := + ∀ m (In : m ∈ M), AllocCond (hist_upto M (loc m) (time m)) m. + + Lemma alloc_inv_val (M : MessageSet) m (In : m ∈ M) : + alloc_inv M → + match val m with + | VInj _ => allocated M (loc m) (time m) + | A => deallocated M (loc m) (Some (time m)) + | D => allocated M (loc m) (time m) + end. + Proof. + move/(_ _ In). rewrite /AllocCond. + case_match. + - case HHist : hist_upto => //. + + Inductive adjacent m1 m2 := adj (EqLoc : m2.(loc) = m1.(loc)) (GtTime : m2.(time) = m1.(time)+1). Definition dealloc_inv (M : MessageSet) := - ∀ m (In : m ∈ M) (IsD : m.(val) = D), MaxTime M m.(loc) (Some m.(time)) ∨ ∃ m', m ∈ M ∧ adjacent m m' ∧ m'.(val) = A. + ∀ m (In : m ∈ M) (IsD : m.(val) = D), inhabited (MaxTime M m.(loc) (Some m.(time))) ∨ ∃ m', m ∈ M ∧ adjacent m m' ∧ m'.(val) = A. Definition alloc_inv (M : MessageSet) := ∀ m (In : m ∈ M), allocated M (m.(loc)) (m.(time)). + + Lemma MT_singl_None `{Dec : ∀ m : message, Decision (P m)} {x v t V l} : (P (<x→v@t,V>) → False) → `(MaxTime (filter P {[<x→v@t,V>]}) l None). + Proof. + move => F; constructor => ? /elem_of_MS_filter [? /elem_of_singleton ?]; by subst. + Qed. + Lemma MT_singl_Some `{Dec : ∀ m : message, Decision (P m)} {x v t V} : (P (<x→v@t,V>)) → `(MaxTime (filter P {[<x→v@t,V>]}) x (Some t)). + Proof. + move => T; econstructor. + - apply/elem_of_MS_filter; split; first eassumption. exact/elem_of_singleton. + - move => ? /elem_of_MS_filter [? /elem_of_singleton ?]. by subst. + Qed. Lemma alloc_thread_red_alloc σ Ï€ x evt V V' σ' acc (HAcc : acc_of evt = Some acc) @@ -756,30 +830,82 @@ Section RAMachine. Proof. inversion ThRed; clear ThRed; inversion DRFRed; clear DRFRed; - inversion AllocRed; clear AllocRed; - subst; + inversion AllocRed; clear AllocRed; + simplify_eq; simpl in HAcc; try by (simplify_option_eq; tauto); try (rewrite LT in LV; inversion LV; subst t0; clear LV); (apply Lt in LT || apply Lt in LV); try by []. - - move => m /elem_of_union [/AllocInv|/elem_of_singleton ->]. - case: (decide (loc m = x0)) => [EqLoc|]. - - (* (move => m /elem_of_union [/AllocInv [? [In [? ?]]]|/elem_of_singleton ->] /= *) - (* ; first (eexists; split; first (apply/elem_of_union; by left); by [])); *) + - move => m /elem_of_join [/AllocInv [t_d t_a TD TA ? ?]|/elem_of_singleton ->]. + + econstructor; eauto; rewrite MS_filter_join; + [rewrite -(join_None t_d)| rewrite -(join_None (Some t_a))]; + apply MaxTime_set_mono => //; exact: MT_singl_None. + + destruct Alloc. econstructor; eauto. + * rewrite MS_filter_join -(join_None t_d). + apply MaxTime_set_mono => //; exact: MT_singl_None. + * rewrite MS_filter_join -(join_None (Some t_a)). + apply MaxTime_set_mono => //; exact: MT_singl_None. + * move/Lt : LV => ?. transitivity tl => //. exact: Pos.lt_le_incl. + - move => m /elem_of_join [/AllocInv [t_d t_a TD TA ? ?]|/elem_of_singleton ->]. + + econstructor; eauto; rewrite MS_filter_join; + [rewrite -(join_None t_d)| rewrite -(join_None (Some t_a))]; + apply MaxTime_set_mono => //; exact: MT_singl_None. + + destruct Alloc. econstructor; eauto. + * rewrite MS_filter_join -(join_None t_d). + apply MaxTime_set_mono => //; exact: MT_singl_None. + * rewrite MS_filter_join -(join_None (Some t_a)). + apply MaxTime_set_mono => //; exact: MT_singl_None. + * move/Lt : LV => ?. transitivity tl => //. exact: Pos.lt_le_incl. + - move => m /elem_of_join [/AllocInv [t_d t_a TD TA ? ?]|/elem_of_singleton ->]. + + case: (decide (loc m = x0)) => [EqLoc|NEqLoc]. + * econstructor; try rewrite MS_filter_join. + { apply: MaxTime_set_mono => //. rewrite EqLoc. exact: MT_singl_Some. } + { rewrite -(join_None (Some _)). apply: MaxTime_set_mono => //. + exact: MT_singl_None. } + { + destruct Alloc. exfalso. apply: Pos.lt_irrefl. + econstructor; eauto; rewrite MS_filter_join; + [rewrite -(join_None t_d)| rewrite -(join_None (Some t_a))]; + apply MaxTime_set_mono => //; exact: alloc_aux1. + + destruct Alloc. econstructor; eauto. + * rewrite MS_filter_join -(join_None t_d). + apply MaxTime_set_mono => //; exact: alloc_aux1. + * rewrite MS_filter_join -(join_None (Some t_a)). + apply MaxTime_set_mono => //; exact: alloc_aux1. + * move/Lt : LV => ?. transitivity tl => //. exact: Pos.lt_le_incl. + + (move => ? /elem_of_join [/AllocInv [? [In [? ?]]]|/elem_of_singleton ->] /= + ; first (eexists; split; first (apply/elem_of_join; by left); by [])). (* try by (destruct Alloc; *) (* inversion TA; *) (* subst; *) (* destruct El as (? & ? & In & ?); *) - (* eexists; split; first (apply/elem_of_union; left; exact: In); intuition; *) + (* eexists; split; first (apply/elem_of_join; left; exact: In); intuition; *) (* transitivity tl => //; exact: Pos.lt_le_incl). *) (* Qed. *) Admitted. - - + + Lemma dealloc_inv_helper1 m (M1 M2 : MessageSet) : + (∃ (m' : message), m ∈ M1 ∧ adjacent m m' ∧ val m' = A) -> + ∃ m' : message, m ∈ M1 ⊔ M2 ∧ adjacent m m' ∧ val m' = A. + Proof. + destruct 1 as (? & In' & ?). eexists. split; last eassumption. + apply/elem_of_join; left; assumption. + Qed. + + Lemma dealloc_inv_helper2 M1 + `(HMax : MaxTime M1 (loc m) (Some (time m))) + `(NEqx : x ≠loc m) v t V : + inhabited (MaxTime (M1 ⊔ {[<x→v@t,(V ⊔ {[x := t]})>]}) (loc m) (Some (time m))). + Proof. + rewrite (_ : Some (time m) = Some (time m) ⊔ None) //. + constructor. apply: MaxTime_set_mono => //. + by constructor => ? /elem_of_singleton -> /NEqx //. + Qed. + Lemma alloc_thread_red_dealloc σ Ï€ x evt V V' σ' acc : acc_of evt = Some acc -> threads σ !! Ï€ = Some V -> thread_red V (mem σ) evt V' (mem σ') -> drf_red σ σ' V x acc -> alloc_red (mem σ) V x evt -> dealloc_inv (mem σ) -> dealloc_inv (mem σ'). @@ -792,71 +918,61 @@ Section RAMachine. inversion LV; subst t0; clear LV); - (apply Lt in LT || apply Lt in LV); try by []. - - move => m /elem_of_union [|/elem_of_singleton ->] /=. - + move => In Eq; move : (DeAllocInv _ In Eq) => [HMax|]. - * destruct Alloc. left. - case: (decide (x0 = loc m)) => [Eqx0|NEqx0]. - (* { intros. rewrite <- Eqx0 in *. *) - (* assert (EqTm : time m = t_d). *) - (* { *) - (* assert (Some t_d ⊆ Some (time m)) *) - (* by (apply: MaxTime_pred_mono; [exact: TD|exact: HMax|by []]). *) - (* assert (time m ≤ t_d). *) - (* { inversion TD. exact: Le. } *) - (* cbn in H4. *) - (* exact: (anti_symm _ _ _ _ H4). *) - (* } *) - (* exfalso. *) - (* rewrite -> EqTm in *. *) - (* assert (t_a ≤ t_d). *) - (* { exact: (MaxTime_pred_mono TA HMax). } *) - (* exact: (proj1 (Pos.le_nlt _ _) _ Alloc). *) - (* } *) - admit. - rewrite (_ : Some (time m) = Some (time m) ∪ None) //. - apply: MaxTime_set_mono => //. - constructor => ? /elem_of_singleton -> /NEqx0. - tauto. - * destruct 1 as (? & In' & ?). right. eexists; split; last eassumption. - apply/elem_of_union; left; assumption. - + by inversion 0. - - move => m /elem_of_union [|/elem_of_singleton ->] /=. - + move => In Eq; move : (DeAllocInv _ In Eq) => [HMax|]. - * destruct Alloc. left. - case: (decide (x0 = loc m)) => [Eqx0|NEqx0]. - (* { intros. rewrite <- Eqx0 in *. *) - (* assert (EqTm : time m = t_d). *) - (* { *) - (* assert (Some t_d ⊆ Some (time m)) *) - (* by (apply: MaxTime_pred_mono; [exact: TD|exact: HMax|by []]). *) - (* assert (time m ≤ t_d). *) - (* { inversion TD. exact: Le. } *) - (* cbn in H4. *) - (* exact: (anti_symm _ _ _ _ H4). *) - (* } *) - (* exfalso. *) - (* rewrite -> EqTm in *. *) - (* assert (t_a ≤ t_d). *) - (* { exact: (MaxTime_pred_mono TA HMax). } *) - (* exact: (proj1 (Pos.le_nlt _ _) _ Alloc). *) - (* } *) - admit. - rewrite (_ : Some (time m) = Some (time m) ∪ None) //. - apply: MaxTime_set_mono => //. - constructor => ? /elem_of_singleton -> /NEqx0. - tauto. - * destruct 1 as (? & In' & ?). right. eexists; split; last eassumption. - apply/elem_of_union; left; assumption. - + by inversion 0. - - move => m /elem_of_union [|/elem_of_singleton ->] /=. + (apply Lt in LT || apply Lt in LV); try by []; + try destruct Alloc; + try destruct Init. + - move => m /elem_of_join [|/elem_of_singleton ->] /=; last (by inversion 0); + move => In Eq; move : (DeAllocInv _ In Eq); intros [[HMax]|]; + [left|right; exact: dealloc_inv_helper1]. + case: (decide (x0 = loc m)) => [Eqx0|NEqx0]; last exact: dealloc_inv_helper2. + exfalso. + move: (MT_fun TD TA) => [] ?; subst. + by apply: StrictOrder_Irreflexive Alloc. + - move => m /elem_of_join [|/elem_of_singleton ->] /=; last (by inversion 0); + move => In Eq; move : (DeAllocInv _ In Eq); intros [[HMax]|]; + [left|right; exact: dealloc_inv_helper1]. + case: (decide (x0 = loc m)) => [Eqx0|NEqx0]; last exact: dealloc_inv_helper2. + exfalso. + move: (MT_fun TD TA) => [] ?; subst. + by apply: StrictOrder_Irreflexive Alloc. + - move => m /elem_of_join [|/elem_of_singleton ->] /=. + + move => In Eq; move : (DeAllocInv _ In Eq); intros [[HMax]|]; + [left|right; exact: dealloc_inv_helper1]. + case: (decide (x0 = loc m)) => [Eqx0|NEqx0]; last exact: dealloc_inv_helper2. + exfalso. + move: (MT_fun TD TA) => [] ?; subst. + by apply: StrictOrder_Irreflexive Alloc. + + move => ?. left. constructor. econstructor. + * apply/elem_of_join. right. apply/elem_of_singleton. + reflexivity. + * move => ? /elem_of_join [In|/elem_of_singleton ->] Eqx0; last reflexivity. + etransitivity. + exact:(MaxTime_Some_Lt Max). + exact: Pos.lt_le_incl. + - move => m /elem_of_join [|/elem_of_singleton ->] /=. + + move => In Eq; move : (DeAllocInv _ In Eq); intros [[HMax]|]; + [left|right; exact: dealloc_inv_helper1]. + case: (decide (x0 = loc m)) => [Eqx0|NEqx0]. + * exfalso. + move: (MT_fun TD TA) => [] ?; subst. + by apply: StrictOrder_Irreflexive Alloc. + * rewrite [_ ⊔ R]comm. + + move => ?. left. constructor. econstructor. + * apply/elem_of_join. right. apply/elem_of_singleton. + reflexivity. + * move => ? /elem_of_join [In|/elem_of_singleton ->] Eqx0; last reflexivity. + etransitivity. + exact:(MaxTime_Some_Lt Max). + exact: Pos.lt_le_incl. + - move => m /elem_of_join [|/elem_of_singleton ->] /=. + - move => m /elem_of_join [|/elem_of_singleton ->] /=. + move => In Eq; move : (DeAllocInv _ In Eq) => [HMax|]. * destruct Alloc. left. case: (decide (x0 = loc m)) => [Eqx0|NEqx0]. (* { intros. rewrite <- Eqx0 in *. *) (* assert (EqTm : time m = t_d). *) (* { *) - (* assert (Some t_d ⊆ Some (time m)) *) + (* assert (Some t_d ⊑ Some (time m)) *) (* by (apply: MaxTime_pred_mono; [exact: TD|exact: HMax|by []]). *) (* assert (time m ≤ t_d). *) (* { inversion TD. exact: Le. } *) @@ -870,20 +986,12 @@ Section RAMachine. (* exact: (proj1 (Pos.le_nlt _ _) _ Alloc). *) (* } *) admit. - rewrite (_ : Some (time m) = Some (time m) ∪ None) //. + rewrite (_ : Some (time m) = Some (time m) ⊔ None) //. apply: MaxTime_set_mono => //. constructor => ? /elem_of_singleton -> /NEqx0. tauto. * destruct 1 as (? & In' & ?). right. eexists; split; last eassumption. - apply/elem_of_union; left; assumption. - + destruct Alloc. - move => ?. left. econstructor. - * apply/elem_of_union. right. apply/elem_of_singleton. - reflexivity. - * move => ? /elem_of_union [In|/elem_of_singleton ->] Eqx0; last reflexivity. - etransitivity. - exact:(MaxTime_Some_Lt Max). - exact: Pos.lt_le_incl. + apply/elem_of_join; left; assumption. Admitted.