Commit 18669b92 by Robbert Krebbers

### Major revision of the whole development.

```The main changes are:

* Function calls in the operational semantics
* Mutually recursive function calls in the axiomatic semantics
* A general definition of the interpretation of the axiomatic semantics  so as
to improve reusability (useful for function calls, and also for expressions
in future versions)
* Type classes for stack independent, memory independent, and memory extensible
assertions, and a lot of instances to automatically derive these properties.
* Many additional lemmas on the memory and more robust tactics to simplify
goals involving is_free and mem_disjoint
* Proof of preservation of statements in the smallstep semantics

* Some new tactics: feed, feed destruct, feed inversion, etc...
* More robust tactic scripts using bullets and structured scripts
* Truncate most lines at 80 characters```
parent a97de42f
This diff is collapsed.
 ... @@ -21,28 +21,36 @@ Section collection. ... @@ -21,28 +21,36 @@ Section collection. Proof. easy. Qed. Proof. easy. Qed. Lemma elem_of_equiv X Y : X ≡ Y ↔ ∀ x, x ∈ X ↔ x ∈ Y. Lemma elem_of_equiv X Y : X ≡ Y ↔ ∀ x, x ∈ X ↔ x ∈ Y. Proof. firstorder. Qed. Proof. firstorder. Qed. Lemma elem_of_equiv_alt X Y : X ≡ Y ↔ (∀ x, x ∈ X → x ∈ Y) ∧ (∀ x, x ∈ Y → x ∈ X). Lemma elem_of_equiv_alt X Y : X ≡ Y ↔ (∀ x, x ∈ X → x ∈ Y) ∧ (∀ x, x ∈ Y → x ∈ X). Proof. firstorder. Qed. Proof. firstorder. Qed. Global Instance: Proper ((=) ==> (≡) ==> iff) (∈). Global Instance: Proper ((=) ==> (≡) ==> iff) (∈). Proof. intros ???. subst. firstorder. Qed. Proof. intros ???. subst. firstorder. Qed. Lemma empty_ne_singleton x : ∅ ≢ {{ x }}. Lemma empty_ne_singleton x : ∅ ≢ {[ x ]}. Proof. intros [_ E]. destruct (elem_of_empty x). apply E. now apply elem_of_singleton. Qed. Proof. intros [_ E]. destruct (elem_of_empty x). apply E. now apply elem_of_singleton. Qed. End collection. End collection. Section cmap. Section cmap. Context `{Collection A C}. Context `{Collection A C}. Lemma elem_of_map_1 (f : A → A) (X : C) (x : A) : x ∈ X → f x ∈ map f X. Lemma elem_of_map_1 (f : A → A) (X : C) (x : A) : x ∈ X → f x ∈ map f X. Proof. intros. apply (elem_of_map _). eauto. Qed. Proof. intros. apply (elem_of_map _). eauto. Qed. Lemma elem_of_map_1_alt (f : A → A) (X : C) (x : A) y : x ∈ X → y = f x → y ∈ map f X. Lemma elem_of_map_1_alt (f : A → A) (X : C) (x : A) y : x ∈ X → y = f x → y ∈ map f X. Proof. intros. apply (elem_of_map _). eauto. Qed. Proof. intros. apply (elem_of_map _). eauto. Qed. Lemma elem_of_map_2 (f : A → A) (X : C) (x : A) : x ∈ map f X → ∃ y, x = f y ∧ y ∈ X. Lemma elem_of_map_2 (f : A → A) (X : C) (x : A) : x ∈ map f X → ∃ y, x = f y ∧ y ∈ X. Proof. intros. now apply (elem_of_map _). Qed. Proof. intros. now apply (elem_of_map _). Qed. End cmap. End cmap. Definition fresh_sig `{FreshSpec A C} (X : C) : { x : A | x ∉ X } := exist (∉ X) (fresh X) (is_fresh X). Definition fresh_sig `{FreshSpec A C} (X : C) : { x : A | x ∉ X } := exist (∉ X) (fresh X) (is_fresh X). Lemma elem_of_fresh_iff `{FreshSpec A C} (X : C) : fresh X ∈ X ↔ False. Lemma elem_of_fresh_iff `{FreshSpec A C} (X : C) : fresh X ∈ X ↔ False. Proof. split. apply is_fresh. easy. Qed. Proof. split. apply is_fresh. easy. Qed. ... @@ -52,7 +60,7 @@ Ltac split_elem_ofs := repeat ... @@ -52,7 +60,7 @@ Ltac split_elem_ofs := repeat | H : context [ _ ⊆ _ ] |- _ => setoid_rewrite elem_of_subseteq in H | H : context [ _ ⊆ _ ] |- _ => setoid_rewrite elem_of_subseteq in H | H : context [ _ ≡ _ ] |- _ => setoid_rewrite elem_of_equiv_alt in H | H : context [ _ ≡ _ ] |- _ => setoid_rewrite elem_of_equiv_alt in H | H : context [ _ ∈ ∅ ] |- _ => setoid_rewrite elem_of_empty_iff in H | H : context [ _ ∈ ∅ ] |- _ => setoid_rewrite elem_of_empty_iff in H | H : context [ _ ∈ {{ _ }} ] |- _ => setoid_rewrite elem_of_singleton in H | H : context [ _ ∈ {[ _ ]} ] |- _ => setoid_rewrite elem_of_singleton in H | H : context [ _ ∈ _ ∪ _ ] |- _ => setoid_rewrite elem_of_union in H | H : context [ _ ∈ _ ∪ _ ] |- _ => setoid_rewrite elem_of_union in H | H : context [ _ ∈ _ ∩ _ ] |- _ => setoid_rewrite elem_of_intersection in H | H : context [ _ ∈ _ ∩ _ ] |- _ => setoid_rewrite elem_of_intersection in H | H : context [ _ ∈ _ ∖ _ ] |- _ => setoid_rewrite elem_of_difference in H | H : context [ _ ∈ _ ∖ _ ] |- _ => setoid_rewrite elem_of_difference in H ... @@ -60,7 +68,7 @@ Ltac split_elem_ofs := repeat ... @@ -60,7 +68,7 @@ Ltac split_elem_ofs := repeat | |- context [ _ ⊆ _ ] => setoid_rewrite elem_of_subseteq | |- context [ _ ⊆ _ ] => setoid_rewrite elem_of_subseteq | |- context [ _ ≡ _ ] => setoid_rewrite elem_of_equiv_alt | |- context [ _ ≡ _ ] => setoid_rewrite elem_of_equiv_alt | |- context [ _ ∈ ∅ ] => setoid_rewrite elem_of_empty_iff | |- context [ _ ∈ ∅ ] => setoid_rewrite elem_of_empty_iff | |- context [ _ ∈ {{ _ }} ] => setoid_rewrite elem_of_singleton | |- context [ _ ∈ {[ _ ]} ] => setoid_rewrite elem_of_singleton | |- context [ _ ∈ _ ∪ _ ] => setoid_rewrite elem_of_union | |- context [ _ ∈ _ ∪ _ ] => setoid_rewrite elem_of_union | |- context [ _ ∈ _ ∩ _ ] => setoid_rewrite elem_of_intersection | |- context [ _ ∈ _ ∩ _ ] => setoid_rewrite elem_of_intersection | |- context [ _ ∈ _ ∖ _ ] => setoid_rewrite elem_of_difference | |- context [ _ ∈ _ ∖ _ ] => setoid_rewrite elem_of_difference ... @@ -97,9 +105,12 @@ Ltac naive_firstorder t := ... @@ -97,9 +105,12 @@ Ltac naive_firstorder t := (* solve *) (* solve *) | |- _ => solve [t] | |- _ => solve [t] (* dirty destructs *) (* dirty destructs *) | H : context [ ∃ _, _ ] |- _ => edestruct H; clear H; naive_firstorder t || clear H; naive_firstorder t | H : context [ ∃ _, _ ] |- _ => | H : context [ _ ∧ _ ] |- _ => edestruct H; clear H; naive_firstorder t || clear H; naive_firstorder t edestruct H; clear H;naive_firstorder t || clear H; naive_firstorder t | H : context [ _ ∨ _ ] |- _ => edestruct H; clear H; naive_firstorder t || clear H; naive_firstorder t | H : context [ _ ∧ _ ] |- _ => destruct H; clear H; naive_firstorder t || clear H; naive_firstorder t | H : context [ _ ∨ _ ] |- _ => edestruct H; clear H; naive_firstorder t || clear H; naive_firstorder t (* dirty constructs *) (* dirty constructs *) | |- ∃ x, _ => eexists; naive_firstorder t | |- ∃ x, _ => eexists; naive_firstorder t | |- _ ∨ _ => left; naive_firstorder t || right; naive_firstorder t | |- _ ∨ _ => left; naive_firstorder t || right; naive_firstorder t ... @@ -125,8 +136,8 @@ Section no_dup. ... @@ -125,8 +136,8 @@ Section no_dup. Global Instance: Proper (R ==> (≡) ==> iff) elem_of_upto. Global Instance: Proper (R ==> (≡) ==> iff) elem_of_upto. Proof. Proof. intros ?? E1 ?? E2. split; intros [z [??]]; exists z. intros ?? E1 ?? E2. split; intros [z [??]]; exists z. rewrite <-E1, <-E2; intuition. * rewrite <-E1, <-E2; intuition. rewrite E1, E2; intuition. * rewrite E1, E2; intuition. Qed. Qed. Global Instance: Proper ((≡) ==> iff) no_dup. Global Instance: Proper ((≡) ==> iff) no_dup. Proof. firstorder. Qed. Proof. firstorder. Qed. ... @@ -135,20 +146,24 @@ Section no_dup. ... @@ -135,20 +146,24 @@ Section no_dup. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Lemma elem_of_upto_empty x : ¬elem_of_upto x ∅. Lemma elem_of_upto_empty x : ¬elem_of_upto x ∅. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Lemma elem_of_upto_singleton x y : elem_of_upto x {{ y }} ↔ R x y. Lemma elem_of_upto_singleton x y : elem_of_upto x {[ y ]} ↔ R x y. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Lemma elem_of_upto_union X Y x : elem_of_upto x (X ∪ Y) ↔ elem_of_upto x X ∨ elem_of_upto x Y. Lemma elem_of_upto_union X Y x : elem_of_upto x (X ∪ Y) ↔ elem_of_upto x X ∨ elem_of_upto x Y. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Lemma not_elem_of_upto x X : ¬elem_of_upto x X → ∀ y, y ∈ X → ¬R x y. Lemma not_elem_of_upto x X : ¬elem_of_upto x X → ∀ y, y ∈ X → ¬R x y. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Proof. unfold elem_of_upto. esimplify_elem_of. Qed. Lemma no_dup_empty: no_dup ∅. Lemma no_dup_empty: no_dup ∅. Proof. unfold no_dup. simplify_elem_of. Qed. Proof. unfold no_dup. simplify_elem_of. Qed. Lemma no_dup_add x X : ¬elem_of_upto x X → no_dup X → no_dup ({{ x }} ∪ X). Lemma no_dup_add x X : ¬elem_of_upto x X → no_dup X → no_dup ({[ x ]} ∪ X). Proof. unfold no_dup, elem_of_upto. esimplify_elem_of. Qed. Proof. unfold no_dup, elem_of_upto. esimplify_elem_of. Qed. Lemma no_dup_inv_add x X : x ∉ X → no_dup ({{ x }} ∪ X) → ¬elem_of_upto x X. Lemma no_dup_inv_add x X : x ∉ X → no_dup ({[ x ]} ∪ X) → ¬elem_of_upto x X. Proof. intros Hin Hnodup [y [??]]. rewrite (Hnodup x y) in Hin; simplify_elem_of. Qed. Proof. intros Hin Hnodup [y [??]]. rewrite (Hnodup x y) in Hin; simplify_elem_of. Qed. Lemma no_dup_inv_union_l X Y : no_dup (X ∪ Y) → no_dup X. Lemma no_dup_inv_union_l X Y : no_dup (X ∪ Y) → no_dup X. Proof. unfold no_dup. simplify_elem_of. Qed. Proof. unfold no_dup. simplify_elem_of. Qed. Lemma no_dup_inv_union_r X Y : no_dup (X ∪ Y) → no_dup Y. Lemma no_dup_inv_union_r X Y : no_dup (X ∪ Y) → no_dup Y. ... @@ -163,7 +178,7 @@ Section quantifiers. ... @@ -163,7 +178,7 @@ Section quantifiers. Lemma cforall_empty : cforall ∅. Lemma cforall_empty : cforall ∅. Proof. unfold cforall. simplify_elem_of. Qed. Proof. unfold cforall. simplify_elem_of. Qed. Lemma cforall_singleton x : cforall {{ x }} ↔ P x. Lemma cforall_singleton x : cforall {[ x ]} ↔ P x. Proof. unfold cforall. simplify_elem_of. Qed. Proof. unfold cforall. simplify_elem_of. Qed. Lemma cforall_union X Y : cforall X → cforall Y → cforall (X ∪ Y). Lemma cforall_union X Y : cforall X → cforall Y → cforall (X ∪ Y). Proof. unfold cforall. simplify_elem_of. Qed. Proof. unfold cforall. simplify_elem_of. Qed. ... @@ -174,7 +189,7 @@ Section quantifiers. ... @@ -174,7 +189,7 @@ Section quantifiers. Lemma cexists_empty : ¬cexists ∅. Lemma cexists_empty : ¬cexists ∅. Proof. unfold cexists. esimplify_elem_of. Qed. Proof. unfold cexists. esimplify_elem_of. Qed. Lemma cexists_singleton x : cexists {{ x }} ↔ P x. Lemma cexists_singleton x : cexists {[ x ]} ↔ P x. Proof. unfold cexists. esimplify_elem_of. Qed. Proof. unfold cexists. esimplify_elem_of. Qed. Lemma cexists_union_1 X Y : cexists X → cexists (X ∪ Y). Lemma cexists_union_1 X Y : cexists X → cexists (X ∪ Y). Proof. unfold cexists. esimplify_elem_of. Qed. Proof. unfold cexists. esimplify_elem_of. Qed. ... @@ -184,9 +199,43 @@ Section quantifiers. ... @@ -184,9 +199,43 @@ Section quantifiers. Proof. unfold cexists. esimplify_elem_of. Qed. Proof. unfold cexists. esimplify_elem_of. Qed. End quantifiers. End quantifiers. Lemma cforall_weak `{Collection A B} (P Q : A → Prop) (Hweak : ∀ x, P x → Q x) X : Section more_quantifiers. cforall P X → cforall Q X. Context `{Collection A B}. Proof. firstorder. Qed. Lemma cexists_weak `{Collection A B} (P Q : A → Prop) (Hweak : ∀ x, P x → Q x) X : Lemma cforall_weak (P Q : A → Prop) (Hweak : ∀ x, P x → Q x) X : cexists P X → cexists Q X. cforall P X → cforall Q X. Proof. firstorder. Qed. Proof. firstorder. Qed. Lemma cexists_weak (P Q : A → Prop) (Hweak : ∀ x, P x → Q x) X : cexists P X → cexists Q X. Proof. firstorder. Qed. End more_quantifiers. Section fresh. Context `{Collection A C} `{Fresh A C} `{!FreshSpec A C} . Fixpoint fresh_list (n : nat) (X : C) : list A := match n with | 0 => [] | S n => let x := fresh X in x :: fresh_list n ({[ x ]} ∪ X) end. Lemma fresh_list_length n X : length (fresh_list n X) = n. Proof. revert X. induction n; simpl; auto. Qed. Lemma fresh_list_is_fresh n X x : In x (fresh_list n X) → x ∉ X. Proof. revert X. induction n; simpl. * easy. * intros X [?| Hin]. subst. + apply is_fresh. + apply IHn in Hin. simplify_elem_of. Qed. Lemma fresh_list_nodup n X : NoDup (fresh_list n X). Proof. revert X. induction n; simpl; constructor; auto. intros Hin. apply fresh_list_is_fresh in Hin. simplify_elem_of. Qed. End fresh.
 ... @@ -6,9 +6,11 @@ Definition decide_rel {A B} (R : A → B → Prop) ... @@ -6,9 +6,11 @@ Definition decide_rel {A B} (R : A → B → Prop) Ltac case_decide := Ltac case_decide := match goal with match goal with | H : context [@decide ?P ?dec] |- _ => case (@decide P dec) in * | H : context [@decide ?P ?dec] |- _ => case (@decide P dec) in * | H : context [@decide_rel _ _ ?R ?x ?y ?dec] |- _ => case (@decide_rel _ _ R x y dec) in * | H : context [@decide_rel _ _ ?R ?x ?y ?dec] |- _ => case (@decide_rel _ _ R x y dec) in * | |- context [@decide ?P ?dec] => case (@decide P dec) in * | |- context [@decide ?P ?dec] => case (@decide P dec) in * | |- context [@decide_rel _ _ ?R ?x ?y ?dec] => case (@decide_rel _ _ R x y dec) in * | |- context [@decide_rel _ _ ?R ?x ?y ?dec] => case (@decide_rel _ _ R x y dec) in * end. end. Ltac solve_trivial_decision := Ltac solve_trivial_decision := ... @@ -16,25 +18,28 @@ Ltac solve_trivial_decision := ... @@ -16,25 +18,28 @@ Ltac solve_trivial_decision := | [ |- Decision (?P) ] => apply _ | [ |- Decision (?P) ] => apply _ | [ |- sumbool ?P (¬?P) ] => change (Decision P); apply _ | [ |- sumbool ?P (¬?P) ] => change (Decision P); apply _ end. end. Ltac solve_decision := Ltac solve_decision := first [solve_trivial_decision | unfold Decision; decide equality; solve_trivial_decision]. intros; first [ solve_trivial_decision | unfold Decision; decide equality; solve_trivial_decision ]. Program Instance True_dec: Decision True := left _. Program Instance True_dec: Decision True := left _. Program Instance False_dec: Decision False := right _. Program Instance False_dec: Decision False := right _. Program Instance prod_eq_dec `(A_dec : ∀ x y : A, Decision (x = y)) Program Instance prod_eq_dec `(A_dec : ∀ x y : A, Decision (x = y)) `(B_dec : ∀ x y : B, Decision (x = y)) : ∀ x y : A * B, Decision (x = y) := λ x y, `(B_dec : ∀ x y : B, Decision (x = y)) : ∀ x y : A * B, Decision (x = y) := λ x y, match A_dec (fst x) (fst y) with match A_dec (fst x) (fst y) with | left _ => match B_dec (snd x) (snd y) with left _ => left _ | right _ => right _ end | left _ => match B_dec (snd x) (snd y) with left _ => left _ | right _ => right _ end | right _ => right _ | right _ => right _ end. end. Solve Obligations using (program_simpl; f_equal; firstorder). Solve Obligations using (program_simpl; f_equal; firstorder). Program Instance and_dec `(P_dec : Decision P) `(Q_dec : Decision Q) : Decision (P ∧ Q) := Program Instance and_dec `(P_dec : Decision P) `(Q_dec : Decision Q) : Decision (P ∧ Q) := match P_dec with match P_dec with | left _ => match Q_dec with left _ => left _ | right _ => right _ end | left _ => match Q_dec with left _ => left _ | right _ => right _ end | right _ => right _ | right _ => right _ end. end. Solve Obligations using (program_simpl; tauto). Solve Obligations using (program_simpl; tauto). Program Instance or_dec `(P_dec : Decision P) `(Q_dec : Decision Q) : Decision (P ∨ Q) := Program Instance or_dec `(P_dec : Decision P) `(Q_dec : Decision Q) : Decision (P ∨ Q) := match P_dec with match P_dec with | left _ => left _ | left _ => left _ | right _ => match Q_dec with left _ => left _ | right _ => right _ end | right _ => match Q_dec with left _ => left _ | right _ => right _ end ... @@ -48,15 +53,22 @@ Proof. unfold bool_decide. now destruct dec. Qed. ... @@ -48,15 +53,22 @@ Proof. unfold bool_decide. now destruct dec. Qed. Lemma bool_decide_pack (P : Prop) {dec : Decision P} : P → bool_decide P. Lemma bool_decide_pack (P : Prop) {dec : Decision P} : P → bool_decide P. Proof. unfold bool_decide. now destruct dec. Qed. Proof. unfold bool_decide. now destruct dec. Qed. Definition dsig `(P : A → Prop) `{∀ x : A, Decision (P x)} := { x | bool_decide (P x) }. Definition dsig `(P : A → Prop) `{∀ x : A, Decision (P x)} := Definition proj2_dsig `{∀ x : A, Decision (P x)} (x : dsig P) : P (`x) := bool_decide_unpack _ (proj2_sig x). { x | bool_decide (P x) }. Definition dexist `{∀ x : A, Decision (P x)} (x : A) (p : P x) : dsig P := x↾bool_decide_pack _ p. Definition proj2_dsig `{∀ x : A, Decision (P x)} (x : dsig P) : P (`x) := bool_decide_unpack _ (proj2_sig x). Definition dexist `{∀ x : A, Decision (P x)} (x : A) (p : P x) : dsig P := x↾bool_decide_pack _ p. Lemma proj1_dsig_inj {A} (P : A → Prop) x (Px : P x) y (Py : P y) : x↾Px = y↾Py → x = y. Lemma proj1_dsig_inj {A} (P : A → Prop) x (Px : P x) y (Py : P y) : x↾Px = y↾Py → x = y. Proof. now injection 1. Qed. Proof. now injection 1. Qed. Lemma dsig_eq {A} (P : A → Prop) {dec : ∀ x, Decision (P x)} (x y : { x | bool_decide (P x) }) : Lemma dsig_eq {A} (P : A → Prop) {dec : ∀ x, Decision (P x)} `x = `y → x = y. (x y : { x | bool_decide (P x) }) : `x = `y → x = y. Proof. Proof. intros H1. destruct x as [x Hx], y as [y Hy]. simpl in *. subst. intros H1. destruct x as [x Hx], y as [y Hy]. f_equal. revert Hx Hy. case (bool_decide (P y)). simpl. now intros [] []. easy. simpl in *. subst. f_equal. revert Hx Hy. case (bool_decide (P y)). * now intros [] []. * easy. Qed. Qed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.