1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 include "paths/standard_trace.ma".
16 include "paths/labeled_sequential_computation.ma".
18 (* DECOMPOSED STANDARD COMPUTATION ***********************************************)
20 (* Note: this is the "standard" computation of:
21 R. Kashima: "A proof of the Standization Theorem in λ-Calculus". (2000).
23 inductive dst: relation term ≝
24 | dst_vref: ∀s,M,i. is_whd s → M ↦*[s] #i → dst M (#i)
25 | dst_abst: ∀s,M,A1,A2. is_whd s → M ↦*[s] 𝛌.A1 → dst A1 A2 → dst M (𝛌.A2)
26 | dst_appl: ∀s,M,B1,B2,A1,A2. is_whd s → M ↦*[s] @B1.A1 → dst B1 B2 → dst A1 A2 → dst M (@B2.A2)
29 interpretation "decomposed standard computation"
30 'DecomposedStd M N = (dst M N).
32 notation "hvbox( M break ⓢ↦* term 46 N )"
33 non associative with precedence 45
34 for @{ 'DecomposedStd $M $N }.
36 lemma dst_inv_lref: ∀M,N. M ⓢ↦* N → ∀j. #j = N →
37 ∃∃s. is_whd s & M ↦*[s] #j.
40 | #s #M #A1 #A2 #_ #_ #_ #j #H destruct
41 | #s #M #B1 #B2 #A1 #A2 #_ #_ #_ #_ #j #H destruct
45 lemma dst_inv_abst: ∀M,N. M ⓢ↦* N → ∀C2. 𝛌.C2 = N →
46 ∃∃s,C1. is_whd s & M ↦*[s] 𝛌.C1 & C1 ⓢ↦* C2.
48 [ #s #M #i #_ #_ #C2 #H destruct
49 | #s #M #A1 #A2 #Hs #HM #A12 #C2 #H destruct /2 width=5/
50 | #s #M #B1 #B2 #A1 #A2 #_ #_ #_ #_ #C2 #H destruct
54 lemma dst_inv_appl: ∀M,N. M ⓢ↦* N → ∀D2,C2. @D2.C2 = N →
55 ∃∃s,D1,C1. is_whd s & M ↦*[s] @D1.C1 & D1 ⓢ↦* D2 & C1 ⓢ↦* C2.
57 [ #s #M #i #_ #_ #D2 #C2 #H destruct
58 | #s #M #A1 #A2 #_ #_ #_ #D2 #C2 #H destruct
59 | #s #M #B1 #B2 #A1 #A2 #Hs #HM #HB12 #HA12 #D2 #C2 #H destruct /2 width=7/
63 lemma dst_refl: reflexive … dst.
64 #M elim M -M /2 width=3/ /2 width=5/ /2 width=7/
67 lemma dst_step_sn: ∀N1,N2. N1 ⓢ↦* N2 → ∀s,M. is_whd s → M ↦*[s] N1 → M ⓢ↦* N2.
68 #N1 #N2 #H elim H -N1 -N2
69 [ #r #N #i #Hr #HN #s #M #Hs #HMN
70 lapply (pl_sreds_trans … HMN … HN) -N /3 width=3/
71 | #r #N #C1 #C2 #Hr #HN #_ #IHC12 #s #M #Hs #HMN
72 lapply (pl_sreds_trans … HMN … HN) -N /3 width=7/
73 | #r #N #D1 #D2 #C1 #C2 #Hr #HN #_ #_ #IHD12 #IHC12 #s #M #Hs #HMN
74 lapply (pl_sreds_trans … HMN … HN) -N /3 width=9/
78 lemma dst_step_rc: ∀s,M1,M2. is_whd s → M1 ↦*[s] M2 → M1 ⓢ↦* M2.
79 /3 width=5 by dst_step_sn/
82 lemma dst_lift: liftable dst.
83 #h #M1 #M2 #H elim H -M1 -M2
85 | #s #M #A1 #A2 #Hs #HM #_ #IHA12 #d
86 @(dst_abst … Hs) [2: @(pl_sreds_lift … HM) | skip ] -M // (**) (* auto fails here *)
87 | #s #M #B1 #B2 #A1 #A2 #Hs #HM #_ #_ #IHB12 #IHA12 #d
88 @(dst_appl … Hs) [3: @(pl_sreds_lift … HM) |1,2: skip ] -M // (**) (* auto fails here *)
92 lemma dst_inv_lift: deliftable_sn dst.
93 #h #N1 #N2 #H elim H -N1 -N2
94 [ #s #N1 #i #Hs #HN1 #d #M1 #HMN1
95 elim (pl_sreds_inv_lift … HN1 … HMN1) -N1 /3 width=3/
96 | #s #N1 #C1 #C2 #Hs #HN1 #_ #IHC12 #d #M1 #HMN1
97 elim (pl_sreds_inv_lift … HN1 … HMN1) -N1 #M2 #HM12 #HM2
98 elim (lift_inv_abst … HM2) -HM2 #A1 #HAC1 #HM2 destruct
99 elim (IHC12 ???) -IHC12 [4: // |2,3: skip ] #A2 #HA12 #HAC2 destruct (**) (* simplify line *)
100 @(ex2_intro … (𝛌.A2)) // /2 width=5/
101 | #s #N1 #D1 #D2 #C1 #C2 #Hs #HN1 #_ #_ #IHD12 #IHC12 #d #M1 #HMN1
102 elim (pl_sreds_inv_lift … HN1 … HMN1) -N1 #M2 #HM12 #HM2
103 elim (lift_inv_appl … HM2) -HM2 #B1 #A1 #HBD1 #HAC1 #HM2 destruct
104 elim (IHD12 ???) -IHD12 [4: // |2,3: skip ] #B2 #HB12 #HBD2 destruct (**) (* simplify line *)
105 elim (IHC12 ???) -IHC12 [4: // |2,3: skip ] #A2 #HA12 #HAC2 destruct (**) (* simplify line *)
106 @(ex2_intro … (@B2.A2)) // /2 width=7/
110 lemma dst_dsubst: dsubstable dst.
111 #N1 #N2 #HN12 #M1 #M2 #H elim H -M1 -M2
112 [ #s #M #i #Hs #HM #d elim (lt_or_eq_or_gt i d) #Hid
113 [ lapply (pl_sreds_dsubst … N1 … HM d) -HM
114 >(dsubst_vref_lt … Hid) >(dsubst_vref_lt … Hid) /2 width=3/
115 | destruct >dsubst_vref_eq
116 @(dst_step_sn (↑[0,i]N1) … s) /2 width=1/
117 | lapply (pl_sreds_dsubst … N1 … HM d) -HM
118 >(dsubst_vref_gt … Hid) >(dsubst_vref_gt … Hid) /2 width=3/
120 | #s #M #A1 #A2 #Hs #HM #_ #IHA12 #d
121 lapply (pl_sreds_dsubst … N1 … HM d) -HM /2 width=5/ (**) (* auto needs some help here *)
122 | #s #M #B1 #B2 #A1 #A2 #Hs #HM #_ #_ #IHB12 #IHA12 #d
123 lapply (pl_sreds_dsubst … N1 … HM d) -HM /2 width=7/ (**) (* auto needs some help here *)
127 lemma dst_step_dx: ∀p,M,M2. M ↦[p] M2 → ∀M1. M1 ⓢ↦* M → M1 ⓢ↦* M2.
128 #p #M #M2 #H elim H -p -M -M2
130 elim (dst_inv_appl … H ???) -H [4: // |2,3: skip ] #s #B1 #M #Hs #HM1 #HB1 #H (**) (* simplify line *)
131 elim (dst_inv_abst … H ??) -H [3: // |2: skip ] #r #A1 #Hr #HM #HA1 (**) (* simplify line *)
132 lapply (pl_sreds_trans … HM1 … (dx:::r) (@B1.𝛌.A1) ?) /2 width=1/ -M #HM1
133 lapply (pl_sreds_step_dx … HM1 (◊) ([↙B1]A1) ?) -HM1 // #HM1
134 @(dst_step_sn … HM1) /2 width=1/ /4 width=1/
135 | #p #A #A2 #_ #IHA2 #M1 #H
136 elim (dst_inv_abst … H ??) -H [3: // |2: skip ] /3 width=5/ (**) (* simplify line *)
137 | #p #B #B2 #A #_ #IHB2 #M1 #H
138 elim (dst_inv_appl … H ???) -H [4: // |2,3: skip ] /3 width=7/ (**) (* simplify line *)
139 | #p #B #A #A2 #_ #IHA2 #M1 #H
140 elim (dst_inv_appl … H ???) -H [4: // |2,3: skip ] /3 width=7/ (**) (* simplify line *)
144 lemma pl_sreds_dst: ∀s,M1,M2. M1 ↦*[s] M2 → M1 ⓢ↦* M2.
145 #s #M1 #M2 #H @(lstar_ind_r ????????? H) -s -M2 // /2 width=4 by dst_step_dx/
148 lemma dst_inv_pl_sreds_is_standard: ∀M,N. M ⓢ↦* N →
149 ∃∃r. M ↦*[r] N & is_standard r.
150 #M #N #H elim H -M -N
152 lapply (is_whd_is_standard … Hs) -Hs /2 width=3/
153 | #s #M #A1 #A2 #Hs #HM #_ * #r #HA12 #Hr
154 lapply (pl_sreds_trans … HM (rc:::r) (𝛌.A2) ?) /2 width=1/ -A1 #HM
155 @(ex2_intro … HM) -M -A2 /3 width=1/
156 | #s #M #B1 #B2 #A1 #A2 #Hs #HM #_ #_ * #rb #HB12 #Hrb * #ra #HA12 #Hra
157 lapply (pl_sreds_trans … HM (dx:::ra) (@B1.A2) ?) /2 width=1/ -A1 #HM
158 lapply (pl_sreds_trans … HM (sn:::rb) (@B2.A2) ?) /2 width=1/ -B1 #HM
159 @(ex2_intro … HM) -M -B2 -A2 >associative_append /3 width=1/
163 theorem dst_trans: transitive … dst.
165 elim (dst_inv_pl_sreds_is_standard … HM1) -HM1 #s1 #HM1 #_
166 elim (dst_inv_pl_sreds_is_standard … HM2) -HM2 #s2 #HM2 #_
167 lapply (pl_sreds_trans … HM1 … HM2) -M /2 width=2/
170 theorem pl_sreds_standard: ∀s,M,N. M ↦*[s] N → ∃∃r. M ↦*[r] N & is_standard r.
172 @dst_inv_pl_sreds_is_standard /2 width=2/
175 (* Note: we use "lapply (rewrite_r ?? is_whd … Hq)" (procedural)
176 in place of "cut (is_whd (q::r)) [ >Hq ]" (declarative)
178 lemma dst_in_whd_swap: ∀p. in_whd p → ∀N1,N2. N1 ↦[p] N2 → ∀M1. M1 ⓢ↦* N1 →
179 ∃∃q,M2. in_whd q & M1 ↦[q] M2 & M2 ⓢ↦* N2.
180 #p #H @(in_whd_ind … H) -p
181 [ #N1 #N2 #H1 #M1 #H2
182 elim (pl_sred_inv_nil … H1 ?) -H1 // #D #C #HN1 #HN2
183 elim (dst_inv_appl … H2 … HN1) -N1 #s1 #D1 #N #Hs1 #HM1 #HD1 #H
184 elim (dst_inv_abst … H ??) -H [3: // |2: skip ] #s2 #C1 #Hs2 #HN #HC1 (**) (* simplify line *)
185 lapply (pl_sreds_trans … HM1 … (dx:::s2) (@D1.𝛌.C1) ?) /2 width=1/ -N #HM1
186 lapply (pl_sreds_step_dx … HM1 (◊) ([↙D1]C1) ?) -HM1 // #HM1
187 elim (pl_sreds_inv_pos … HM1 ?) -HM1
188 [2: >length_append normalize in ⊢ (??(??%)); // ]
189 #q #r #M #Hq #HM1 #HM
190 lapply (rewrite_r ?? is_whd … Hq) -Hq /4 width=1/ -s1 -s2 * #Hq #Hr
191 @(ex3_2_intro … HM1) -M1 // -q
192 @(dst_step_sn … HM) /2 width=1/
193 | #p #_ #IHp #N1 #N2 #H1 #M1 #H2
194 elim (pl_sred_inv_dx … H1 ??) -H1 [3: // |2: skip ] #D #C1 #C2 #HC12 #HN1 #HN2 (**) (* simplify line *)
195 elim (dst_inv_appl … H2 … HN1) -N1 #s #B #A1 #Hs #HM1 #HBD #HAC1
196 elim (IHp … HC12 … HAC1) -p -C1 #p #C1 #Hp #HAC1 #HC12
197 lapply (pl_sreds_step_dx … HM1 (dx::p) (@B.C1) ?) -HM1 /2 width=1/ -A1 #HM1
198 elim (pl_sreds_inv_pos … HM1 ?) -HM1
199 [2: >length_append normalize in ⊢ (??(??%)); // ]
200 #q #r #M #Hq #HM1 #HM
201 lapply (rewrite_r ?? is_whd … Hq) -Hq /4 width=1/ -p -s * #Hq #Hr
202 @(ex3_2_intro … HM1) -M1 // -q /2 width=7/
206 theorem pl_sreds_in_whd_swap: ∀s,M1,N1. M1 ↦*[s] N1 →
207 ∀p,N2. in_whd p → N1 ↦[p] N2 →
208 ∃∃q,r,M2. in_whd q & M1 ↦[q] M2 & M2 ↦*[r] N2 &
210 #s #M1 #N1 #HMN1 #p #N2 #Hp #HN12
211 lapply (pl_sreds_dst … HMN1) -s #HMN1
212 elim (dst_in_whd_swap … Hp … HN12 … HMN1) -p -N1 #q #M2 #Hq #HM12 #HMN2
213 elim (dst_inv_pl_sreds_is_standard … HMN2) -HMN2 /3 width=8/