aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LICENSE30
-rw-r--r--README.md38
-rw-r--r--complete.v58
-rw-r--r--expr.v6
-rw-r--r--flake.nix1
-rw-r--r--maptools.v63
-rw-r--r--matching.v29
-rw-r--r--relations.v19
-rw-r--r--semprop.v197
-rw-r--r--shared.v11
-rw-r--r--sound.v56
11 files changed, 221 insertions, 287 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c1ab0b4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
1All files in this repository are available for use under the BSD 3-Clause "New"
2or "Revised License". The terms of the license are included below.
3SPDX license identifier: BSD-3-Clause.
4
5=====================================
6
7Copyright (c) 2024 Rutger Broekhoff.
8
9Redistribution and use in source and binary forms, with or without
10modification, are permitted provided that the following conditions are met:
11
121. Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
142. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
173. Neither the name of the copyright holder nor the names of its contributors
18 may be used to endorse or promote products derived from this software
19 without specific prior written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..125ea10
--- /dev/null
+++ b/README.md
@@ -0,0 +1,38 @@
1Coq Formalization for Mininix
2=============================
3
4[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
5
6Mininix is a smaller version of the Nix expression language. This repository
7provides the mechanization of the semantics and reference interpreter for this
8language in the [Coq](https://coq.inria.fr/) proof assistant. For more details,
9I refer to my bachelor' thesis. I will link to it when it is made available on
10the [thesis archive](https://www.cs.ru.nl/bachelors-theses/) page of
11[iCIS](https://www.ru.nl/en/institute-for-computing-and-information-sciences).
12
13## Development
14
15During my thesis, I used Nix to manage the Coq installation for this thesis.
16If you use Nix, it should be easy to build/check the codebase. If not, this
17might be a bit more tricky.
18
19### Using Nix
20
21I have attached a `flake.nix` and `flake.lock` file, which should make my setup
22reproducible. Assuming a working Nix installation with flake support and the
23Nix command enabled, simply running `nix develop` followed by `make` should run
24`coqc` on all files. If you have a working [direnv](https://direnv.net/)
25installation, simply running `direnv allow` (after inspecting the `.envrc`
26file) should make the right version of Coq available.
27
28### Without Nix
29
30There are two things you need to have available. The current `flake.lock`
31ensures that we have the following software:
32
33- Coq, version 8.19.2.
34- [Coq-std++](https://gitlab.mpi-sws.org/iris/stdpp), version 1.10.0.
35 You may be able to install Coq-std++ via opam, as described in the README of
36 Coq-std++. However, your operating system's package repositories may also
37 provide a package. Consider taking a look at [the Repology
38 page](https://repology.org/project/coq-stdpp/packages).
diff --git a/complete.v b/complete.v
index 9939b50..5a2ccdc 100644
--- a/complete.v
+++ b/complete.v
@@ -34,36 +34,34 @@ Proof.
34 induction v using strong_value_ind'; try by exists 2. 34 induction v using strong_value_ind'; try by exists 2.
35 unfold expr_from_strong_value. simpl. 35 unfold expr_from_strong_value. simpl.
36 fold expr_from_strong_value. 36 fold expr_from_strong_value.
37 induction bs using map_ind. 37 induction bs using map_ind; [by exists 2|].
38 + by exists 2. 38 apply map_Forall_insert in H as [[n Hn] H2]; try done.
39 + apply map_Forall_insert in H as [[n Hn] H2]; try done. 39 apply IHbs in H2 as [o Ho]. clear IHbs.
40 apply IHbs in H2 as [o Ho]. clear IHbs. 40 exists (S (n `max` o)).
41 exists (S (n `max` o)). 41 rewrite eval_S. csimpl.
42 rewrite eval_S. csimpl. 42 setoid_rewrite map_mapM_Some_2_L
43 setoid_rewrite map_mapM_Some_2_L 43 with (m2 := value_from_strong_value <$> <[i := x]>m);
44 with (m2 := value_from_strong_value <$> <[i := x]>m); csimpl. 44 csimpl; [by rewrite <-map_fmap_compose|].
45 * by rewrite <-map_fmap_compose. 45 destruct o as [|o]; csimpl in *; try discriminate.
46 * destruct o as [|o]; csimpl in *; try discriminate. 46 apply map_Forall2_alt_L.
47 apply map_Forall2_alt_L. 47 split; [set_solver|].
48 split. 48 intros j u v ??. rewrite eval_S in Ho.
49 -- set_solver. 49 apply bind_Some in Ho as [vs [Ho1 Ho2]].
50 -- intros j u v ??. rewrite eval_S in Ho. 50 setoid_rewrite map_mapM_Some_L in Ho1. simplify_eq.
51 apply bind_Some in Ho as [vs [Ho1 Ho2]]. 51 unfold expr_from_strong_value in Ho2.
52 setoid_rewrite map_mapM_Some_L in Ho1. simplify_eq. 52 rewrite map_fmap_compose in Ho2.
53 unfold expr_from_strong_value in Ho2. 53 simplify_eq.
54 rewrite map_fmap_compose in Ho2. 54 destruct (decide (i = j)).
55 simplify_eq. 55 - simplify_eq.
56 destruct (decide (i = j)). 56 repeat rewrite lookup_fmap, lookup_insert in *.
57 ++ simplify_eq. 57 simplify_eq/=.
58 repeat rewrite lookup_fmap, lookup_insert in *. 58 apply eval_le with (n := n); lia || done.
59 simplify_eq/=. 59 - repeat rewrite lookup_fmap, lookup_insert_ne in * by done.
60 apply eval_le with (n := n); lia || done. 60 repeat rewrite <-lookup_fmap in *.
61 ++ repeat rewrite lookup_fmap, lookup_insert_ne in * by done. 61 apply map_Forall2_alt_L in Ho1.
62 repeat rewrite <-lookup_fmap in *. 62 destruct Ho1 as [Ho1 Ho2].
63 apply map_Forall2_alt_L in Ho1. 63 apply eval_le with (n := o); try lia.
64 destruct Ho1 as [Ho1 Ho2]. 64 by apply Ho2 with (i := j).
65 apply eval_le with (n := o); try lia.
66 by apply Ho2 with (i := j).
67Qed. 65Qed.
68 66
69Lemma eval_force_strong_value' v : 67Lemma eval_force_strong_value' v :
diff --git a/expr.v b/expr.v
index 11c0737..e770345 100644
--- a/expr.v
+++ b/expr.v
@@ -60,6 +60,12 @@ Instance Maybe_X_Attrset : Maybe X_Attrset := λ e,
60 | _ => None 60 | _ => None
61 end. 61 end.
62 62
63Instance Maybe_X_V : Maybe X_V := λ e,
64 match e with
65 | X_V v => Some v
66 | _ => None
67 end.
68
63Instance Maybe_B_Nonrec : Maybe B_Nonrec := λ rhs, 69Instance Maybe_B_Nonrec : Maybe B_Nonrec := λ rhs,
64 match rhs with 70 match rhs with
65 | B_Nonrec e => Some e 71 | B_Nonrec e => Some e
diff --git a/flake.nix b/flake.nix
index e9c35a4..25361d2 100644
--- a/flake.nix
+++ b/flake.nix
@@ -12,7 +12,6 @@
12 { 12 {
13 devShells.default = with pkgs; mkShell { 13 devShells.default = with pkgs; mkShell {
14 buildInputs = [ 14 buildInputs = [
15 coqPackages.coqide
16 coqPackages.stdpp 15 coqPackages.stdpp
17 coq 16 coq
18 ]; 17 ];
diff --git a/maptools.v b/maptools.v
index 2478430..ce4022a 100644
--- a/maptools.v
+++ b/maptools.v
@@ -4,8 +4,8 @@ From stdpp Require Import countable fin_maps fin_map_dom.
4(** Generic lemmas for finite maps and their domains *) 4(** Generic lemmas for finite maps and their domains *)
5 5
6Lemma map_insert_empty_lookup {A} `{FinMap K M} 6Lemma map_insert_empty_lookup {A} `{FinMap K M}
7 (i j : K) (u v : A) : 7 (i j : K) (x y : A) :
8 <[i := u]> (∅ : M A) !! j = Some v → i = j ∧ v = u. 8 <[i := x]> (∅ : M A) !! j = Some y → i = j ∧ y = x.
9Proof. 9Proof.
10 intros Hiel. 10 intros Hiel.
11 destruct (decide (i = j)). 11 destruct (decide (i = j)).
@@ -106,6 +106,32 @@ Lemma map_dom_insert_eq_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A}
106 dom (delete i m1) = dom (delete i m2) ∧ i ∈ dom m2. 106 dom (delete i m1) = dom (delete i m2) ∧ i ∈ dom m2.
107Proof. set_solver. Qed. 107Proof. set_solver. Qed.
108 108
109(* Copied from stdpp and changed so that the value types
110 of m1 and m2 are decoupled *)
111Lemma map_dom_subseteq_size `{FinMapDom K M D} {A B} (m1 : M A) (m2 : M B) :
112 dom m2 ⊆ dom m1 → size m2 ≤ size m1.
113Proof.
114 revert m1. induction m2 as [|i x m2 ? IH] using map_ind; intros m1 Hdom.
115 { rewrite map_size_empty. lia. }
116 rewrite dom_insert in Hdom.
117 assert (i ∉ dom m2) by (by apply not_elem_of_dom).
118 assert (i ∈ dom m1) as [x' Hx'] % elem_of_dom by set_solver.
119 rewrite <-(insert_delete m1 i x') by done.
120 rewrite !map_size_insert_None, <-Nat.succ_le_mono
121 by (by rewrite ?lookup_delete).
122 apply IH. rewrite dom_delete. set_solver.
123Qed.
124
125Lemma map_dom_empty_subset `{Countable K} `{FinMapDom K M D} {A B} (m : M A) :
126 dom m ⊆ dom (∅ : M B) → m = ∅.
127Proof.
128 intros Hdom.
129 apply map_dom_subseteq_size in Hdom.
130 rewrite map_size_empty in Hdom.
131 inv Hdom.
132 by apply map_size_empty_inv.
133Qed.
134
109(** map_mapM *) 135(** map_mapM *)
110 136
111Definition map_mapM {M : Type → Type} `{MBind F} `{MRet F} `{FinMap K M} {A B} 137Definition map_mapM {M : Type → Type} `{MBind F} `{MRet F} `{FinMap K M} {A B}
@@ -137,11 +163,10 @@ Proof.
137Qed. 163Qed.
138 164
139Lemma map_mapM_option_insert_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B} 165Lemma map_mapM_option_insert_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B}
140 (f : A → option B) (m1 : M A) (m2 m2' : M B) 166 (f : A → option B) (m1 : M A) (m2 m2' : M B) (i : K) (x : A) :
141 (i : K) (x : A) (x' : B) : 167 m1 !! i = None →
142 m1 !! i = None → 168 map_mapM f (<[i := x]>m1) = Some m2 →
143 map_mapM f (<[i := x]>m1) = Some m2 → 169 ∃ x', f x = Some x' ∧ map_mapM f m1 = Some (delete i m2).
144 ∃ x', f x = Some x' ∧ map_mapM f m1 = Some (delete i m2).
145Proof. 170Proof.
146 intros Helem HmapM. 171 intros Helem HmapM.
147 unfold map_mapM in HmapM. 172 unfold map_mapM in HmapM.
@@ -315,7 +340,7 @@ Qed.
315 340
316Lemma map_Forall2_impl_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B} 341Lemma map_Forall2_impl_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B}
317 (R1 R2 : A → B → Prop) : 342 (R1 R2 : A → B → Prop) :
318 (∀ a b, R1 a b → R2 a b) → 343 (∀ x y, R1 x y → R2 x y) →
319 ∀ (m1 : M A) (m2 : M B), 344 ∀ (m1 : M A) (m2 : M B),
320 map_Forall2 R1 m1 m2 → map_Forall2 R2 m1 m2. 345 map_Forall2 R1 m1 m2 → map_Forall2 R2 m1 m2.
321Proof. 346Proof.
@@ -327,8 +352,8 @@ Proof.
327Qed. 352Qed.
328 353
329Lemma map_Forall2_fmap_r_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B C} 354Lemma map_Forall2_fmap_r_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B C}
330 (P : A → C → Prop) (m1 : M A) (m2 : M B) (f : B → C) : 355 (R : A → C → Prop) (m1 : M A) (m2 : M B) (f : B → C) :
331 map_Forall2 P m1 (f <$> m2) → map_Forall2 (λ l r, P l (f r)) m1 m2. 356 map_Forall2 R m1 (f <$> m2) → map_Forall2 (λ x y, R x (f y)) m1 m2.
332Proof. 357Proof.
333 intros HForall2. 358 intros HForall2.
334 unfold map_Forall2, map_relation, option_relation in *. 359 unfold map_Forall2, map_relation, option_relation in *.
@@ -355,10 +380,10 @@ Proof.
355Qed. 380Qed.
356 381
357Lemma map_insert_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A} 382Lemma map_insert_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A}
358 (i : K) (x1 x2 : A) (m1 m2 : M A) : 383 (i : K) (x y : A) (m1 m2 : M A) :
359 x1 = x2 384 x = y
360 delete i m1 = delete i m2 → 385 delete i m1 = delete i m2 →
361 <[i := x1]>m1 = <[i := x2]>m2. 386 <[i := x]>m1 = <[i := y]>m2.
362Proof. 387Proof.
363 intros Heq Hdel. 388 intros Heq Hdel.
364 apply map_Forall2_eq_L. 389 apply map_Forall2_eq_L.
@@ -367,8 +392,8 @@ Proof.
367Qed. 392Qed.
368 393
369Lemma map_insert_rev_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A} 394Lemma map_insert_rev_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A}
370 (i : K) (x1 x2 : A) (m1 m2 : M A) : 395 (m1 m2 : M A) (i : K) (x y : A) :
371 <[i := x1]>m1 = <[i := x2]>m2 → x1 = x2 ∧ delete i m1 = delete i m2. 396 <[i := x]>m1 = <[i := y]>m2 → x = y ∧ delete i m1 = delete i m2.
372Proof. 397Proof.
373 intros Heq. apply map_Forall2_eq_L in Heq. 398 intros Heq. apply map_Forall2_eq_L in Heq.
374 apply map_Forall2_insert_inv in Heq as [Heq1 Heq2]. 399 apply map_Forall2_insert_inv in Heq as [Heq1 Heq2].
@@ -376,13 +401,13 @@ Proof.
376Qed. 401Qed.
377 402
378Lemma map_insert_rev_1_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A} 403Lemma map_insert_rev_1_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A}
379 (i : K) (x1 x2 : A) (m1 m2 : M A) : 404 (m1 m2 : M A) (i : K) (x y : A) :
380 <[i := x1]>m1 = <[i := x2]>m2 → x1 = x2. 405 <[i := x]>m1 = <[i := y]>m2 → x = y.
381Proof. apply map_insert_rev_L. Qed. 406Proof. apply map_insert_rev_L. Qed.
382 407
383Lemma map_insert_rev_2_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A} 408Lemma map_insert_rev_2_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A}
384 (i : K) (x1 x2 : A) (m1 m2 : M A) : 409 (m1 m2 : M A) (i : K) (x y : A) :
385 <[i := x1]>m1 = <[i := x2]>m2 → delete i m1 = delete i m2. 410 <[i := x]>m1 = <[i := y]>m2 → delete i m1 = delete i m2.
386Proof. apply map_insert_rev_L. Qed. 411Proof. apply map_insert_rev_L. Qed.
387 412
388Lemma map_Forall2_alt_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B} 413Lemma map_Forall2_alt_L `{FinMapDom K M D} `{!LeibnizEquiv D} {A B}
diff --git a/matching.v b/matching.v
index 494bb92..cb09690 100644
--- a/matching.v
+++ b/matching.v
@@ -64,32 +64,6 @@ Definition matches (m : matcher) (bs : gmap string expr) :
64 snd <$> matches_aux ms bs 64 snd <$> matches_aux ms bs
65 end. 65 end.
66 66
67(* Copied from stdpp and changed so that the value types
68 of m1 and m2 are decoupled *)
69Lemma dom_subseteq_size' `{FinMapDom K M D} {A B} (m1 : M A) (m2 : M B) :
70 dom m2 ⊆ dom m1 → size m2 ≤ size m1.
71Proof.
72 revert m1. induction m2 as [|i x m2 ? IH] using map_ind; intros m1 Hdom.
73 { rewrite map_size_empty. lia. }
74 rewrite dom_insert in Hdom.
75 assert (i ∉ dom m2) by (by apply not_elem_of_dom).
76 assert (i ∈ dom m1) as [x' Hx']%elem_of_dom by set_solver.
77 rewrite <-(insert_delete m1 i x') by done.
78 rewrite !map_size_insert_None, <-Nat.succ_le_mono
79 by (by rewrite ?lookup_delete).
80 apply IH. rewrite dom_delete. set_solver.
81Qed.
82
83Lemma dom_empty_subset `{Countable K} `{FinMapDom K M D} {A B} (m : M A) :
84 dom m ⊆ dom (∅ : M B) → m = ∅.
85Proof.
86 intros Hdom.
87 apply dom_subseteq_size' in Hdom.
88 rewrite map_size_empty in Hdom.
89 inv Hdom.
90 by apply map_size_empty_inv.
91Qed.
92
93Lemma matches_aux_empty bs : matches_aux ∅ bs = Some (bs, ∅). 67Lemma matches_aux_empty bs : matches_aux ∅ bs = Some (bs, ∅).
94Proof. done. Qed. 68Proof. done. Qed.
95 69
@@ -496,8 +470,7 @@ Proof.
496 revert strict bs brs Hmatches. 470 revert strict bs brs Hmatches.
497 induction ms using map_ind; intros strict bs brs Hmatches. 471 induction ms using map_ind; intros strict bs brs Hmatches.
498 - destruct strict; simplify_option_eq. 472 - destruct strict; simplify_option_eq.
499 + apply dom_empty_subset in H0. simplify_eq. 473 + apply map_dom_empty_subset in H0. simplify_eq. constructor.
500 constructor.
501 + constructor. 474 + constructor.
502 - destruct x. 475 - destruct x.
503 + apply matches_step' in Hmatches as He. 476 + apply matches_step' in Hmatches as He.
diff --git a/relations.v b/relations.v
index 9bfb7e6..7523c96 100644
--- a/relations.v
+++ b/relations.v
@@ -1,10 +1,14 @@
1(** This files contains definitions for determinism, strong confluence,
2 * semi-confluence, the Church-Rosser property and proofs about relationships
3 * of these properties. We use definitions and proofs from 'Term Rewriting and
4 * All That' by Franz Baader and Tobias Nipkow (1998). *)
1From stdpp Require Import relations. 5From stdpp Require Import relations.
2 6
3Definition deterministic {A} (R : relation A) := 7Definition deterministic {A} (R : relation A) :=
4 ∀ x y1 y2, R x y1 → R x y2 → y1 = y2. 8 ∀ x y1 y2, R x y1 → R x y2 → y1 = y2.
5 9
6(* As in Baader and Nipkow (1998): *) 10(** Baader and Nipkow (1998), p. 9:
7(* y is a normal form of x if x -->* y and y is in normal form. *) 11 * y is a normal form of x if x -->* y and y is in normal form. *)
8Definition is_nf_of `(R : relation A) x y := (rtc R x y) ∧ nf R y. 12Definition is_nf_of `(R : relation A) x y := (rtc R x y) ∧ nf R y.
9 13
10(** The reflexive closure. *) 14(** The reflexive closure. *)
@@ -14,15 +18,15 @@ Inductive rc {A} (R : relation A) : relation A :=
14 18
15Hint Constructors rc : core. 19Hint Constructors rc : core.
16 20
17(* Baader and Nipkow, Definition 2.7.3. *) 21(** Baader and Nipkow, Definition 2.7.3. *)
18Definition strongly_confluent {A} (R : relation A) := 22Definition strongly_confluent {A} (R : relation A) :=
19 ∀ x y1 y2, R x y1 → R x y2 → ∃ z, rtc R y1 z ∧ rc R y2 z. 23 ∀ x y1 y2, R x y1 → R x y2 → ∃ z, rtc R y1 z ∧ rc R y2 z.
20 24
21(* Baader and Nipkow, Definition 2.1.4. *) 25(** Baader and Nipkow, Definition 2.1.4. *)
22Definition semi_confluent {A} (R : relation A) := 26Definition semi_confluent {A} (R : relation A) :=
23 ∀ x y1 y2, R x y1 → rtc R x y2 → ∃ z, rtc R y1 z ∧ rtc R y2 z. 27 ∀ x y1 y2, R x y1 → rtc R x y2 → ∃ z, rtc R y1 z ∧ rtc R y2 z.
24 28
25(* Lemma 2.7.4 from Baader and Nipkow *) 29(** Lemma 2.7.4 from Baader and Nipkow *)
26Lemma strong__semi_confluence {A} (R : relation A) : 30Lemma strong__semi_confluence {A} (R : relation A) :
27 strongly_confluent R → semi_confluent R. 31 strongly_confluent R → semi_confluent R.
28Proof. 32Proof.
@@ -47,11 +51,12 @@ Proof.
47 by apply rtc_transitive with (y := y2). 51 by apply rtc_transitive with (y := y2).
48Qed. 52Qed.
49 53
50(* Copied from stdpp, originates from Baader and Nipkow (1998) *) 54(** Baader and Nipkow, Definition 2.1.3.
55 * Copied from stdpp v1.10.0 (confluent_alt). *)
51Definition cr {A} (R : relation A) := 56Definition cr {A} (R : relation A) :=
52 ∀ x y, rtsc R x y → ∃ z, rtc R x z ∧ rtc R y z. 57 ∀ x y, rtsc R x y → ∃ z, rtc R x z ∧ rtc R y z.
53 58
54(* Part of Lemma 2.1.5 from Baader and Nipkow (1998) *) 59(** Part of Lemma 2.1.5 from Baader and Nipkow (1998) *)
55Lemma semi_confluence__cr {A} (R : relation A) : 60Lemma semi_confluence__cr {A} (R : relation A) :
56 semi_confluent R → cr R. 61 semi_confluent R → cr R.
57Proof. 62Proof.
diff --git a/semprop.v b/semprop.v
index 3af718d..2fe30af 100644
--- a/semprop.v
+++ b/semprop.v
@@ -77,173 +77,36 @@ Proof.
77 intros b11 b12 b21 b22 E2 Hbase1 Hbase2 Hctx2 H2; inv Hctx2. 77 intros b11 b12 b21 b22 E2 Hbase1 Hbase2 Hctx2 H2; inv Hctx2.
78 - (* L: id, R: id *) left. by eapply base_step_deterministic. 78 - (* L: id, R: id *) left. by eapply base_step_deterministic.
79 - (* L: id, R: ∘ *) simplify_eq/=. 79 - (* L: id, R: ∘ *) simplify_eq/=.
80 inv H. 80 inv H; try inv select (_ -->base b12);
81 + inv Hbase1. 81 (inv select (is_ctx _ _ _);
82 * inv H0. 82 [inv select (b21 -->base b22)
83 -- inv Hbase2. 83 |inv select (is_ctx_item _ _ _)]).
84 -- inv H. 84 simplify_option_eq.
85 * inv H0. 85 destruct sv; try discriminate.
86 -- inv Hbase2. 86 exfalso. clear uf. simplify_option_eq.
87 -- inv H1. inv H. 87 apply fmap_insert_lookup in H1. simplify_option_eq.
88 + inv Hbase1. 88 revert bs0 x H H1 Heqo.
89 * inv H0. 89 induction H2; intros bs0 x H' H1 Heqo; [inv Hbase2|].
90 -- inv Hbase2. 90 simplify_option_eq.
91 -- inv H. 91 inv H. destruct H'; try discriminate.
92 * inv H0. 92 inv H1. apply fmap_insert_lookup in H0. simplify_option_eq.
93 -- inv Hbase2. 93 by eapply IHis_ctx.
94 -- inv H. 94 - (* L: ∘, R: id *) simplify_eq/=.
95 + inv Hbase1. 95 inv H; try inv select (_ -->base b22);
96 * inv H0. 96 (inv select (is_ctx _ _ _);
97 -- inv Hbase2. 97 [inv select (b11 -->base b12)
98 -- inv H. 98 |inv select (is_ctx_item _ _ _)]).
99 * inv H0. 99 clear IHHctx1.
100 -- inv Hbase2. 100 simplify_option_eq.
101 -- inv H1. 101 destruct sv; try discriminate.
102 + inv Hbase1. 102 exfalso. simplify_option_eq.
103 * inv H0. 103 apply fmap_insert_lookup in H0. simplify_option_eq.
104 -- inv Hbase2. 104 revert bs0 x H H0 Heqo.
105 -- inv H. 105 induction H1; intros bs0 x H' H0 Heqo; [inv Hbase1|].
106 * inv H0. 106 simplify_option_eq.
107 -- inv Hbase2. 107 inv H. destruct H'; try discriminate.
108 -- inv H1. 108 inv H0. apply fmap_insert_lookup in H2. simplify_option_eq.
109 * inv H0. 109 by eapply IHis_ctx.
110 -- inv Hbase2.
111 -- inv H1. inv H.
112 + inv Hbase1.
113 inv H0.
114 * inv Hbase2.
115 * inv H.
116 + inv Hbase1.
117 * inv H0.
118 -- inv Hbase2.
119 -- inv H.
120 * inv H0.
121 -- inv Hbase2.
122 -- inv H.
123 + inv Hbase1.
124 inv H0.
125 * inv Hbase2.
126 * inv H.
127 + inv Hbase1.
128 inv H0.
129 * inv Hbase2.
130 * inv H.
131 + inv Hbase1.
132 inv H0.
133 * inv Hbase2.
134 * inv H.
135 + inv Hbase1.
136 * inv H0.
137 -- inv Hbase2.
138 -- inv H1.
139 * inv H0.
140 -- inv Hbase2.
141 -- inv H1.
142 * inv H0.
143 -- inv Hbase2.
144 -- inv H1.
145 + inv Hbase1.
146 inv H0.
147 * inv Hbase2.
148 * inv H.
149 simplify_option_eq.
150 destruct sv; try discriminate.
151 exfalso. clear uf. simplify_option_eq.
152 apply fmap_insert_lookup in H1. simplify_option_eq.
153 revert bs0 x H H1 Heqo.
154 induction H2; intros bs0 x H' H1 Heqo.
155 -- inv Hbase2.
156 -- simplify_option_eq.
157 inv H. destruct H'; try discriminate.
158 inv H1. apply fmap_insert_lookup in H0. simplify_option_eq.
159 by eapply IHis_ctx.
160 + inv Hbase1.
161 - (* L: ∘, R: id *)
162 simplify_eq/=.
163 inv H.
164 + inv Hbase2.
165 * inv Hctx1.
166 -- inv Hbase1.
167 -- inv H.
168 * inv Hctx1.
169 -- inv Hbase1.
170 -- inv H0. inv H.
171 + inv Hbase2.
172 * inv Hctx1.
173 -- inv Hbase1.
174 -- inv H.
175 * inv Hctx1.
176 -- inv Hbase1.
177 -- inv H.
178 + inv Hbase2.
179 * inv Hctx1.
180 -- inv Hbase1.
181 -- inv H.
182 * inv Hctx1.
183 -- inv Hbase1.
184 -- inv H0.
185 + inv Hbase2.
186 * inv Hctx1.
187 -- inv Hbase1.
188 -- inv H.
189 * inv Hctx1.
190 -- inv Hbase1.
191 -- inv H0.
192 * inv Hctx1.
193 -- inv Hbase1.
194 -- inv H0. inv H.
195 + inv Hbase2.
196 inv Hctx1.
197 * inv Hbase1.
198 * inv H.
199 + inv Hbase2.
200 * inv Hctx1.
201 -- inv Hbase1.
202 -- inv H.
203 * inv Hctx1.
204 -- inv Hbase1.
205 -- inv H.
206 + inv Hbase2.
207 inv Hctx1.
208 * inv Hbase1.
209 * inv H.
210 + inv Hbase2.
211 inv Hctx1.
212 * inv Hbase1.
213 * inv H.
214 + inv Hbase2.
215 inv Hctx1.
216 * inv Hbase1.
217 * inv H.
218 + inv Hbase2.
219 * inv Hctx1.
220 -- inv Hbase1.
221 -- inv H0.
222 * inv Hctx1.
223 -- inv Hbase1.
224 -- inv H0.
225 * inv Hctx1.
226 -- inv Hbase1.
227 -- inv H0.
228 + inv Hbase2.
229 inv Hctx1.
230 * inv Hbase1.
231 * clear IHHctx1.
232 inv H.
233 simplify_option_eq.
234 destruct sv; try discriminate.
235 exfalso. simplify_option_eq.
236 apply fmap_insert_lookup in H0. simplify_option_eq.
237 revert bs0 x H H0 Heqo.
238 induction H1; intros bs0 x H' H0 Heqo.
239 -- inv Hbase1.
240 -- simplify_option_eq.
241 inv H. destruct H'; try discriminate.
242 inv H0. apply fmap_insert_lookup in H2. simplify_option_eq.
243 eapply IHis_ctx.
244 ++ apply H2.
245 ++ apply Heqo0.
246 + inv Hbase2.
247 - (* L: ∘, R: ∘ *) 110 - (* L: ∘, R: ∘ *)
248 simplify_option_eq. 111 simplify_option_eq.
249 inv H; inv H0. 112 inv H; inv H0.
diff --git a/shared.v b/shared.v
index 8e9484f..2365c9d 100644
--- a/shared.v
+++ b/shared.v
@@ -14,12 +14,11 @@ Definition nonrecs : gmap string b_rhs → gmap string expr :=
14 14
15Lemma nonrecs_nonrec_fmap bs : nonrecs (B_Nonrec <$> bs) = bs. 15Lemma nonrecs_nonrec_fmap bs : nonrecs (B_Nonrec <$> bs) = bs.
16Proof. 16Proof.
17 induction bs using map_ind. 17 induction bs using map_ind; [done|].
18 - done. 18 unfold nonrecs.
19 - unfold nonrecs. 19 rewrite fmap_insert.
20 rewrite fmap_insert. 20 rewrite omap_insert_Some with (y := x); try done.
21 rewrite omap_insert_Some with (y := x); try done. 21 by f_equal.
22 by f_equal.
23Qed. 22Qed.
24 23
25Lemma rec_subst_nonrec_fmap bs : rec_subst (B_Nonrec <$> bs) = bs. 24Lemma rec_subst_nonrec_fmap bs : rec_subst (B_Nonrec <$> bs) = bs.
diff --git a/sound.v b/sound.v
index 761d7ad..2ae5001 100644
--- a/sound.v
+++ b/sound.v
@@ -13,9 +13,8 @@ Lemma strong_value_stuck_rtc sv e:
13 expr_from_strong_value sv -->* e → 13 expr_from_strong_value sv -->* e →
14 e = expr_from_strong_value sv. 14 e = expr_from_strong_value sv.
15Proof. 15Proof.
16 intros. inv H. 16 intros. inv H; [done|].
17 - reflexivity. 17 exfalso. apply strong_value_stuck with (sv := sv). by exists y.
18 - exfalso. apply strong_value_stuck with (sv := sv). by exists y.
19Qed. 18Qed.
20 19
21Lemma force__strong_value (e : expr) (v : value) : 20Lemma force__strong_value (e : expr) (v : value) :
@@ -68,33 +67,32 @@ Lemma force_map_fmap_union_insert (sws : gmap string strong_value) es k e sv :
68Proof. 67Proof.
69 intros [n Hsteps] % rtc_nsteps. 68 intros [n Hsteps] % rtc_nsteps.
70 revert sws es k e Hsteps. 69 revert sws es k e Hsteps.
71 induction n; intros sws es k e Hsteps. 70 induction n; intros sws es k e Hsteps; [inv Hsteps|].
72 - inv Hsteps. 71 inv Hsteps.
73 - inv Hsteps. 72 inv H0.
74 inv H0. 73 inv H2.
75 inv H2. 74 - inv H3. inv H1.
76 + inv H3. inv H1. 75 + simplify_option_eq. unfold expr_from_strong_value, compose.
77 * simplify_option_eq. unfold expr_from_strong_value, compose. 76 by rewrite H4.
78 by rewrite H4. 77 + edestruct strong_value_stuck. exists y. done.
79 * edestruct strong_value_stuck. exists y. done. 78 - inv H0. simplify_option_eq.
80 + inv H0. simplify_option_eq. 79 apply rtc_transitive
81 apply rtc_transitive 80 with (y := X_Force (X_V (V_Attrset (<[k:=E2 e2]> es ∪
82 with (y := X_Force (X_V (V_Attrset (<[k:=E2 e2]> es ∪ 81 (expr_from_strong_value <$> sws))))).
83 (expr_from_strong_value <$> sws))))). 82 + do 2 rewrite <-insert_union_l.
84 * do 2 rewrite <-insert_union_l. 83 apply rtc_once.
85 apply rtc_once. 84 eapply E_Ctx
86 eapply E_Ctx 85 with (E := λ e, X_Force (X_V (V_Attrset (<[k := E2 e]>(es ∪
87 with (E := λ e, X_Force (X_V (V_Attrset (<[k := E2 e]>(es ∪ 86 (expr_from_strong_value <$> sws)))))).
88 (expr_from_strong_value <$> sws)))))). 87 * eapply IsCtx_Compose.
89 -- eapply IsCtx_Compose. 88 -- constructor.
89 -- eapply IsCtx_Compose
90 with (E1 := (λ e, X_V (V_Attrset (<[k := e]>(es ∪
91 (expr_from_strong_value <$> sws)))))).
90 ++ constructor. 92 ++ constructor.
91 ++ eapply IsCtx_Compose 93 ++ done.
92 with (E1 := (λ e, X_V (V_Attrset (<[k := e]>(es ∪ 94 * done.
93 (expr_from_strong_value <$> sws)))))). 95 + by apply IHn.
94 ** constructor.
95 ** done.
96 -- done.
97 * by apply IHn.
98Qed. 96Qed.
99 97
100Lemma insert_union_fmap__union_fmap_insert {A B} (f : A → B) i x 98Lemma insert_union_fmap__union_fmap_insert {A B} (f : A → B) i x