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 "ground/notation/relations/rcoafter_3.ma".
16 include "ground/relocation/rtmap_sor.ma".
17 include "ground/relocation/rtmap_nat.ma".
18 include "ground/relocation/rtmap_after.ma".
20 (* RELOCATION MAP ***********************************************************)
22 coinductive coafter: relation3 rtmap rtmap rtmap ≝
23 | coafter_refl: ∀f1,f2,f,g1,g2,g. coafter f1 f2 f →
24 ⫯f1 = g1 → ⫯f2 = g2 → ⫯f = g → coafter g1 g2 g
25 | coafter_push: ∀f1,f2,f,g1,g2,g. coafter f1 f2 f →
26 ⫯f1 = g1 → ↑f2 = g2 → ↑f = g → coafter g1 g2 g
27 | coafter_next: ∀f1,f2,f,g1,g. coafter f1 f2 f →
28 ↑f1 = g1 → ⫯f = g → coafter g1 f2 g
31 interpretation "relational co-composition (rtmap)"
32 'RCoAfter f1 f2 f = (coafter f1 f2 f).
34 definition H_coafter_inj: predicate rtmap ≝
36 ∀f,f21,f22. f1 ~⊚ f21 ≘ f → f1 ~⊚ f22 ≘ f → f21 ≡ f22.
38 definition H_coafter_fwd_isid2: predicate rtmap ≝
39 λf1. ∀f2,f. f1 ~⊚ f2 ≘ f → 𝐓❪f1❫ → 𝐈❪f❫ → 𝐈❪f2❫.
41 definition H_coafter_isfin2_fwd: predicate rtmap ≝
42 λf1. ∀f2. 𝐅❪f2❫ → 𝐓❪f1❫ → ∀f. f1 ~⊚ f2 ≘ f → 𝐅❪f❫.
44 (* Basic inversion lemmas ***************************************************)
46 lemma coafter_inv_ppx: ∀g1,g2,g. g1 ~⊚ g2 ≘ g → ∀f1,f2. ⫯f1 = g1 → ⫯f2 = g2 →
47 ∃∃f. f1 ~⊚ f2 ≘ f & ⫯f = g.
48 #g1 #g2 #g * -g1 -g2 -g #f1 #f2 #f #g1
49 [ #g2 #g #Hf #H1 #H2 #H #x1 #x2 #Hx1 #Hx2 destruct
50 >(injective_push … Hx1) >(injective_push … Hx2) -x2 -x1
51 /2 width=3 by ex2_intro/
52 | #g2 #g #_ #_ #H2 #_ #x1 #x2 #_ #Hx2 destruct
53 elim (discr_push_next … Hx2)
54 | #g #_ #H1 #_ #x1 #x2 #Hx1 #_ destruct
55 elim (discr_push_next … Hx1)
59 lemma coafter_inv_pnx: ∀g1,g2,g. g1 ~⊚ g2 ≘ g → ∀f1,f2. ⫯f1 = g1 → ↑f2 = g2 →
60 ∃∃f. f1 ~⊚ f2 ≘ f & ↑f = g.
61 #g1 #g2 #g * -g1 -g2 -g #f1 #f2 #f #g1
62 [ #g2 #g #_ #_ #H2 #_ #x1 #x2 #_ #Hx2 destruct
63 elim (discr_next_push … Hx2)
64 | #g2 #g #Hf #H1 #H2 #H3 #x1 #x2 #Hx1 #Hx2 destruct
65 >(injective_push … Hx1) >(injective_next … Hx2) -x2 -x1
66 /2 width=3 by ex2_intro/
67 | #g #_ #H1 #_ #x1 #x2 #Hx1 #_ destruct
68 elim (discr_push_next … Hx1)
72 lemma coafter_inv_nxx: ∀g1,f2,g. g1 ~⊚ f2 ≘ g → ∀f1. ↑f1 = g1 →
73 ∃∃f. f1 ~⊚ f2 ≘ f & ⫯f = g.
74 #g1 #f2 #g * -g1 -f2 -g #f1 #f2 #f #g1
75 [ #g2 #g #_ #H1 #_ #_ #x1 #Hx1 destruct
76 elim (discr_next_push … Hx1)
77 | #g2 #g #_ #H1 #_ #_ #x1 #Hx1 destruct
78 elim (discr_next_push … Hx1)
79 | #g #Hf #H1 #H #x1 #Hx1 destruct
80 >(injective_next … Hx1) -x1
81 /2 width=3 by ex2_intro/
85 (* Advanced inversion lemmas ************************************************)
87 lemma coafter_inv_ppp: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
88 ∀f1,f2,f. ⫯f1 = g1 → ⫯f2 = g2 → ⫯f = g → f1 ~⊚ f2 ≘ f.
89 #g1 #g2 #g #Hg #f1 #f2 #f #H1 #H2 #H
90 elim (coafter_inv_ppx … Hg … H1 H2) -g1 -g2 #x #Hf #Hx destruct
91 <(injective_push … Hx) -f //
94 lemma coafter_inv_ppn: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
95 ∀f1,f2,f. ⫯f1 = g1 → ⫯f2 = g2 → ↑f = g → ⊥.
96 #g1 #g2 #g #Hg #f1 #f2 #f #H1 #H2 #H
97 elim (coafter_inv_ppx … Hg … H1 H2) -g1 -g2 #x #Hf #Hx destruct
98 elim (discr_push_next … Hx)
101 lemma coafter_inv_pnn: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
102 ∀f1,f2,f. ⫯f1 = g1 → ↑f2 = g2 → ↑f = g → f1 ~⊚ f2 ≘ f.
103 #g1 #g2 #g #Hg #f1 #f2 #f #H1 #H2 #H
104 elim (coafter_inv_pnx … Hg … H1 H2) -g1 -g2 #x #Hf #Hx destruct
105 <(injective_next … Hx) -f //
108 lemma coafter_inv_pnp: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
109 ∀f1,f2,f. ⫯f1 = g1 → ↑f2 = g2 → ⫯f = g → ⊥.
110 #g1 #g2 #g #Hg #f1 #f2 #f #H1 #H2 #H
111 elim (coafter_inv_pnx … Hg … H1 H2) -g1 -g2 #x #Hf #Hx destruct
112 elim (discr_next_push … Hx)
115 lemma coafter_inv_nxp: ∀g1,f2,g. g1 ~⊚ f2 ≘ g →
116 ∀f1,f. ↑f1 = g1 → ⫯f = g → f1 ~⊚ f2 ≘ f.
117 #g1 #f2 #g #Hg #f1 #f #H1 #H
118 elim (coafter_inv_nxx … Hg … H1) -g1 #x #Hf #Hx destruct
119 <(injective_push … Hx) -f //
122 lemma coafter_inv_nxn: ∀g1,f2,g. g1 ~⊚ f2 ≘ g →
123 ∀f1,f. ↑f1 = g1 → ↑f = g → ⊥.
124 #g1 #f2 #g #Hg #f1 #f #H1 #H
125 elim (coafter_inv_nxx … Hg … H1) -g1 #x #Hf #Hx destruct
126 elim (discr_push_next … Hx)
129 lemma coafter_inv_pxp: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
130 ∀f1,f. ⫯f1 = g1 → ⫯f = g →
131 ∃∃f2. f1 ~⊚ f2 ≘ f & ⫯f2 = g2.
132 #g1 #g2 #g #Hg #f1 #f #H1 #H elim (pn_split g2) * #f2 #H2
133 [ lapply (coafter_inv_ppp … Hg … H1 H2 H) -g1 -g /2 width=3 by ex2_intro/
134 | elim (coafter_inv_pnp … Hg … H1 H2 H)
138 lemma coafter_inv_pxn: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
139 ∀f1,f. ⫯f1 = g1 → ↑f = g →
140 ∃∃f2. f1 ~⊚ f2 ≘ f & ↑f2 = g2.
141 #g1 #g2 #g #Hg #f1 #f #H1 #H elim (pn_split g2) * #f2 #H2
142 [ elim (coafter_inv_ppn … Hg … H1 H2 H)
143 | lapply (coafter_inv_pnn … Hg … H1 … H) -g1 -g /2 width=3 by ex2_intro/
147 lemma coafter_inv_xxn: ∀g1,g2,g. g1 ~⊚ g2 ≘ g → ∀f. ↑f = g →
148 ∃∃f1,f2. f1 ~⊚ f2 ≘ f & ⫯f1 = g1 & ↑f2 = g2.
149 #g1 #g2 #g #Hg #f #H elim (pn_split g1) * #f1 #H1
150 [ elim (coafter_inv_pxn … Hg … H1 H) -g /2 width=5 by ex3_2_intro/
151 | elim (coafter_inv_nxn … Hg … H1 H)
155 lemma coafter_inv_xnn: ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
156 ∀f2,f. ↑f2 = g2 → ↑f = g →
157 ∃∃f1. f1 ~⊚ f2 ≘ f & ⫯f1 = g1.
158 #g1 #g2 #g #Hg #f2 #f #H2 destruct #H
159 elim (coafter_inv_xxn … Hg … H) -g
160 #z1 #z2 #Hf #H1 #H2 destruct /2 width=3 by ex2_intro/
163 lemma coafter_inv_xxp: ∀g1,g2,g. g1 ~⊚ g2 ≘ g → ∀f. ⫯f = g →
164 (∃∃f1,f2. f1 ~⊚ f2 ≘ f & ⫯f1 = g1 & ⫯f2 = g2) ∨
165 ∃∃f1. f1 ~⊚ g2 ≘ f & ↑f1 = g1.
166 #g1 #g2 #g #Hg #f #H elim (pn_split g1) * #f1 #H1
167 [ elim (coafter_inv_pxp … Hg … H1 H) -g
168 /3 width=5 by or_introl, ex3_2_intro/
169 | /4 width=5 by coafter_inv_nxp, or_intror, ex2_intro/
173 lemma coafter_inv_pxx: ∀g1,g2,g. g1 ~⊚ g2 ≘ g → ∀f1. ⫯f1 = g1 →
174 (∃∃f2,f. f1 ~⊚ f2 ≘ f & ⫯f2 = g2 & ⫯f = g) ∨
175 (∃∃f2,f. f1 ~⊚ f2 ≘ f & ↑f2 = g2 & ↑f = g).
176 #g1 #g2 #g #Hg #f1 #H1 elim (pn_split g2) * #f2 #H2
177 [ elim (coafter_inv_ppx … Hg … H1 H2) -g1
178 /3 width=5 by or_introl, ex3_2_intro/
179 | elim (coafter_inv_pnx … Hg … H1 H2) -g1
180 /3 width=5 by or_intror, ex3_2_intro/
184 (* Basic properties *********************************************************)
186 corec lemma coafter_eq_repl_back2: ∀f1,f. eq_repl_back (λf2. f2 ~⊚ f1 ≘ f).
187 #f1 #f #f2 * -f2 -f1 -f
188 #f21 #f1 #f #g21 [1,2: #g1 ] #g #Hf #H21 [1,2: #H1 ] #H #g22 #H0
189 [ cases (eq_inv_px … H0 … H21) -g21 /3 width=7 by coafter_refl/
190 | cases (eq_inv_px … H0 … H21) -g21 /3 width=7 by coafter_push/
191 | cases (eq_inv_nx … H0 … H21) -g21 /3 width=5 by coafter_next/
195 lemma coafter_eq_repl_fwd2: ∀f1,f. eq_repl_fwd (λf2. f2 ~⊚ f1 ≘ f).
196 #f1 #f @eq_repl_sym /2 width=3 by coafter_eq_repl_back2/
199 corec lemma coafter_eq_repl_back1: ∀f2,f. eq_repl_back (λf1. f2 ~⊚ f1 ≘ f).
200 #f2 #f #f1 * -f2 -f1 -f
201 #f2 #f11 #f #g2 [1,2: #g11 ] #g #Hf #H2 [1,2: #H11 ] #H #g2 #H0
202 [ cases (eq_inv_px … H0 … H11) -g11 /3 width=7 by coafter_refl/
203 | cases (eq_inv_nx … H0 … H11) -g11 /3 width=7 by coafter_push/
204 | @(coafter_next … H2 H) /2 width=5 by/
208 lemma coafter_eq_repl_fwd1: ∀f2,f. eq_repl_fwd (λf1. f2 ~⊚ f1 ≘ f).
209 #f2 #f @eq_repl_sym /2 width=3 by coafter_eq_repl_back1/
212 corec lemma coafter_eq_repl_back0: ∀f1,f2. eq_repl_back (λf. f2 ~⊚ f1 ≘ f).
213 #f2 #f1 #f * -f2 -f1 -f
214 #f2 #f1 #f01 #g2 [1,2: #g1 ] #g01 #Hf01 #H2 [1,2: #H1 ] #H01 #g02 #H0
215 [ cases (eq_inv_px … H0 … H01) -g01 /3 width=7 by coafter_refl/
216 | cases (eq_inv_nx … H0 … H01) -g01 /3 width=7 by coafter_push/
217 | cases (eq_inv_px … H0 … H01) -g01 /3 width=5 by coafter_next/
221 lemma coafter_eq_repl_fwd0: ∀f2,f1. eq_repl_fwd (λf. f2 ~⊚ f1 ≘ f).
222 #f2 #f1 @eq_repl_sym /2 width=3 by coafter_eq_repl_back0/
225 (* Main inversion lemmas ****************************************************)
227 corec theorem coafter_mono: ∀f1,f2,x,y. f1 ~⊚ f2 ≘ x → f1 ~⊚ f2 ≘ y → x ≡ y.
228 #f1 #f2 #x #y * -f1 -f2 -x
229 #f1 #f2 #x #g1 [1,2: #g2 ] #g #Hx #H1 [1,2: #H2 ] #H0x #Hy
230 [ cases (coafter_inv_ppx … Hy … H1 H2) -g1 -g2 /3 width=8 by eq_push/
231 | cases (coafter_inv_pnx … Hy … H1 H2) -g1 -g2 /3 width=8 by eq_next/
232 | cases (coafter_inv_nxx … Hy … H1) -g1 /3 width=8 by eq_push/
236 lemma coafter_mono_eq: ∀f1,f2,f. f1 ~⊚ f2 ≘ f → ∀g1,g2,g. g1 ~⊚ g2 ≘ g →
237 f1 ≡ g1 → f2 ≡ g2 → f ≡ g.
238 /4 width=4 by coafter_mono, coafter_eq_repl_back1, coafter_eq_repl_back2/ qed-.
240 (* Forward lemmas with pushs ************************************************)
242 lemma coafter_fwd_pushs: ∀k,l,g2,f1,g. g2 ~⊚ ⫯*[l]f1 ≘ g → @↑❪l, g2❫ ≘ k →
243 ∃∃f. ⫱*[k]g2 ~⊚ f1 ≘ f & ⫯*[k] f = g.
244 #k @(nat_ind_succ … k) -k
245 [ #l #g2 #f1 #g #Hg #H
246 elim (rm_nat_inv_xxp … H) -H [|*: // ] #f2 #H1 #H2 destruct
247 /2 width=3 by ex2_intro/
248 | #k #IH * [| #l ] #g2 #f1 #g #Hg #H
249 [ elim (rm_nat_inv_pxn … H) -H [|*: // ] #f2 #Hlk #H destruct
250 elim (coafter_inv_nxx … Hg) -Hg [|*: // ] #f #Hf #H destruct
251 elim (IH … Hf Hlk) -IH -Hf -Hlk /2 width=3 by ex2_intro/
252 | elim (rm_nat_inv_nxn … H) -H [1,4: * |*: // ] #f2 #Hlk #H destruct
253 [ elim (coafter_inv_ppx … Hg) -Hg [|*: // ] #f #Hf #H destruct
254 elim (IH … Hf Hlk) -IH -Hf -Hlk /2 width=3 by ex2_intro/
255 | elim (coafter_inv_nxx … Hg) -Hg [|*: // ] #f #Hf #H destruct
256 elim (IH … Hf Hlk) -IH -Hf -Hlk /2 width=3 by ex2_intro/
262 (* Inversion lemmas with tail ***********************************************)
264 lemma coafter_inv_tl1: ∀g2,g1,g. g2 ~⊚ ⫱g1 ≘ g →
265 ∃∃f. ⫯g2 ~⊚ g1 ≘ f & ⫱f = g.
266 #g2 #g1 #g elim (pn_split g1) * #f1 #H1 #H destruct
267 [ /3 width=7 by coafter_refl, ex2_intro/
268 | @(ex2_intro … (↑g)) /2 width=7 by coafter_push/ (**) (* full auto fails *)
272 lemma coafter_inv_tl0: ∀g2,g1,g. g2 ~⊚ g1 ≘ ⫱g →
273 ∃∃f1. ⫯g2 ~⊚ f1 ≘ g & ⫱f1 = g1.
274 #g2 #g1 #g elim (pn_split g) * #f #H0 #H destruct
275 [ /3 width=7 by coafter_refl, ex2_intro/
276 | @(ex2_intro … (↑g1)) /2 width=7 by coafter_push/ (**) (* full auto fails *)
280 (* Properties with iterated tail ********************************************)
282 lemma coafter_tls: ∀l2,l1,f1,f2,f. @↑❪l1, f1❫ ≘ l2 →
283 f1 ~⊚ f2 ≘ f → ⫱*[l2]f1 ~⊚ ⫱*[l1]f2 ≘ ⫱*[l2]f.
284 #l2 @(nat_ind_succ … l2) -l2 [ #l1 | #l2 #IH * [| #l1 ] ] #f1 #f2 #f #Hf1 #Hf
285 [ elim (rm_nat_inv_xxp … Hf1) -Hf1 [ |*: // ] #g1 #Hg1 #H1 destruct //
286 | elim (rm_nat_inv_pxn … Hf1) -Hf1 [ |*: // ] #g1 #Hg1 #H1
287 elim (coafter_inv_nxx … Hf … H1) -Hf #g #Hg #H0 destruct
288 lapply (IH … Hg1 Hg) -IH -Hg1 -Hg //
289 | elim (rm_nat_inv_xxn … Hf1) -Hf1 [1,3: * |*: // ] #g1 [ #k1 ] #Hg1 [ #H ] #H1
290 [ elim (coafter_inv_pxx … Hf … H1) -Hf * #g2 #g #Hg #H2 #H0 destruct
291 lapply (IH … Hg1 Hg) -IH -Hg1 -Hg #H //
292 | elim (coafter_inv_nxx … Hf … H1) -Hf #g #Hg #H0 destruct
293 lapply (IH … Hg1 Hg) -IH -Hg1 -Hg #H //
298 lemma coafter_tls_O: ∀k,f1,f2,f. @↑❪𝟎, f1❫ ≘ k →
299 f1 ~⊚ f2 ≘ f → ⫱*[k]f1 ~⊚ f2 ≘ ⫱*[k]f.
300 /2 width=1 by coafter_tls/ qed.
302 (* Note: this does not require ↑ first and second j *)
303 lemma coafter_tls_succ: ∀g2,g1,g. g2 ~⊚ g1 ≘ g →
304 ∀j. @❪𝟏, g2❫ ≘ j → ⫱*[j]g2 ~⊚ ⫱g1 ≘ ⫱*[j]g.
305 #g2 #g1 #g #Hg #j #Hg2
306 lapply (rm_nat_pred_bi … Hg2) -Hg2 #Hg2
307 lapply (coafter_tls … Hg2 … Hg) -Hg #Hg
308 lapply (at_pxx_tls … Hg2) -Hg2 #H
309 elim (at_inv_pxp … H) -H [ |*: // ] #f2 #H2
310 elim (coafter_inv_pxx … Hg … H2) -Hg * #f1 #f #Hf #H1 #H0
311 >(npsucc_pred j) <tls_S <tls_S //
314 lemma coafter_fwd_xpx_pushs: ∀g2,f1,g,i,j. @❪i, g2❫ ≘ j → g2 ~⊚ ⫯*[i]⫯f1 ≘ g →
315 ∃∃f. ⫱*[↑j]g2 ~⊚ f1 ≘ f & ⫯*[j]⫯f = g.
316 #g2 #g1 #g #i #j #Hg2 <pushs_xn #Hg(coafter_fwd_pushs … Hg Hg2) #f #H0 destruct
317 lapply (coafter_tls … Hg2 Hg) -Hg <tls_pushs <tls_pushs #Hf
318 lapply (at_inv_tls … Hg2) -Hg2 #H
319 lapply (coafter_eq_repl_fwd2 … Hf … H) -H -Hf #Hf
320 elim (coafter_inv_ppx … Hf) [|*: // ] -Hf #g #Hg #H destruct
321 /2 width=3 by ex2_intro/
324 lemma coafter_fwd_xnx_pushs: ∀g2,f1,g,i,j. @❪i, g2❫ ≘ j → g2 ~⊚ ⫯*[i]↑f1 ≘ g →
325 ∃∃f. ⫱*[↑j]g2 ~⊚ f1 ≘ f & ⫯*[j] ↑f = g.
326 #g2 #g1 #g #i #j #Hg2 #Hg
327 elim (coafter_fwd_pushs … Hg Hg2) #f #H0 destruct
328 lapply (coafter_tls … Hg2 Hg) -Hg <tls_pushs <tls_pushs #Hf
329 lapply (at_inv_tls … Hg2) -Hg2 #H
330 lapply (coafter_eq_repl_fwd2 … Hf … H) -H -Hf #Hf
331 elim (coafter_inv_pnx … Hf) [|*: // ] -Hf #g #Hg #H destruct
332 /2 width=3 by ex2_intro/
335 (* Properties with test for identity ****************************************)
337 corec lemma coafter_isid_sn: ∀f1. 𝐈❪f1❫ → ∀f2. f1 ~⊚ f2 ≘ f2.
338 #f1 * -f1 #f1 #g1 #Hf1 #H1 #f2 cases (pn_split f2) * #g2 #H2
339 /3 width=7 by coafter_push, coafter_refl/
342 corec lemma coafter_isid_dx: ∀f2,f. 𝐈❪f2❫ → 𝐈❪f❫ → ∀f1. f1 ~⊚ f2 ≘ f.
343 #f2 #f * -f2 #f2 #g2 #Hf2 #H2 * -f #f #g #Hf #H #f1 cases (pn_split f1) * #g1 #H1
344 [ /3 width=7 by coafter_refl/
345 | @(coafter_next … H1 … H) /3 width=3 by isid_push/
349 (* Inversion lemmas with test for identity **********************************)
351 lemma coafter_isid_inv_sn: ∀f1,f2,f. f1 ~⊚ f2 ≘ f → 𝐈❪f1❫ → f2 ≡ f.
352 /3 width=6 by coafter_isid_sn, coafter_mono/ qed-.
354 lemma coafter_isid_inv_dx: ∀f1,f2,f. f1 ~⊚ f2 ≘ f → 𝐈❪f2❫ → 𝐈❪f❫.
355 /4 width=4 by eq_id_isid, coafter_isid_dx, coafter_mono/ qed-.
357 (* Forward lemmas with istot ************************************************)
359 corec fact coafter_inj_O_aux: ∀f1. @❪𝟏, f1❫ ≘ 𝟏 → H_coafter_inj f1.
360 #f1 #H1f1 #H2f1 #f #f21 #f22 #H1f #H2f
361 cases (at_inv_pxp … H1f1) -H1f1 [ |*: // ] #g1 #H1
362 lapply (istot_inv_push … H2f1 … H1) -H2f1 #H2g1
363 cases (H2g1 (𝟏)) #n #Hn
364 cases (coafter_inv_pxx … H1f … H1) -H1f * #g21 #g #H1g #H21 #H
365 [ cases (coafter_inv_pxp … H2f … H1 H) -f1 -f #g22 #H2g #H22
366 @(eq_push … H21 H22) -f21 -f22
367 | cases (coafter_inv_pxn … H2f … H1 H) -f1 -f #g22 #H2g #H22
368 @(eq_next … H21 H22) -f21 -f22
370 @(coafter_inj_O_aux (⫱*[↓n]g1) … (⫱*[↓n]g)) -coafter_inj_O_aux
371 /2 width=1 by coafter_tls, istot_tls, at_pxx_tls/
374 fact coafter_inj_aux: (∀f1. @❪𝟏, f1❫ ≘ 𝟏 → H_coafter_inj f1) →
375 ∀i2,f1. @❪𝟏, f1❫ ≘ i2 → H_coafter_inj f1.
376 #H0 #i2 elim i2 -i2 /2 width=1 by/ -H0
377 #i2 #IH #f1 #H1f1 #H2f1 #f #f21 #f22 #H1f #H2f
378 elim (at_inv_pxn … H1f1) -H1f1 [ |*: // ] #g1 #H1g1 #H1
379 elim (coafter_inv_nxx … H1f … H1) -H1f #g #H1g #H
380 lapply (coafter_inv_nxp … H2f … H1 H) -f #H2g
381 /3 width=6 by istot_inv_next/
384 theorem coafter_inj: ∀f1. H_coafter_inj f1.
385 #f1 #H cases (H (𝟏)) /3 width=7 by coafter_inj_aux, coafter_inj_O_aux/
388 corec fact coafter_fwd_isid2_O_aux: ∀f1. @❪𝟏, f1❫ ≘ 𝟏 →
389 H_coafter_fwd_isid2 f1.
390 #f1 #H1f1 #f2 #f #H #H2f1 #Hf
391 cases (at_inv_pxp … H1f1) -H1f1 [ |*: // ] #g1 #H1
392 lapply (istot_inv_push … H2f1 … H1) -H2f1 #H2g1
393 cases (H2g1 (𝟏)) #n #Hn
394 cases (coafter_inv_pxx … H … H1) -H * #g2 #g #H #H2 #H0
395 [ lapply (isid_inv_push … Hf … H0) -Hf #Hg
396 @(isid_push … H2) -H2
397 /3 width=7 by coafter_tls_O, at_pxx_tls, istot_tls, isid_tls/
398 | cases (isid_inv_next … Hf … H0)
402 fact coafter_fwd_isid2_aux: (∀f1. @❪𝟏, f1❫ ≘ 𝟏 → H_coafter_fwd_isid2 f1) →
403 ∀i2,f1. @❪𝟏, f1❫ ≘ i2 → H_coafter_fwd_isid2 f1.
404 #H0 #i2 elim i2 -i2 /2 width=1 by/ -H0
405 #i2 #IH #f1 #H1f1 #f2 #f #H #H2f1 #Hf
406 elim (at_inv_pxn … H1f1) -H1f1 [ |*: // ] #g1 #Hg1 #H1
407 elim (coafter_inv_nxx … H … H1) -H #g #Hg #H0
408 @(IH … Hg1 … Hg) /2 width=3 by istot_inv_next, isid_inv_push/ (**) (* full auto fails *)
411 lemma coafter_fwd_isid2: ∀f1. H_coafter_fwd_isid2 f1.
412 #f1 #f2 #f #Hf #H cases (H (𝟏))
413 /3 width=7 by coafter_fwd_isid2_aux, coafter_fwd_isid2_O_aux/
416 fact coafter_isfin2_fwd_O_aux: ∀f1. @❪𝟏, f1❫ ≘ 𝟏 →
417 H_coafter_isfin2_fwd f1.
419 generalize in match Hf1; generalize in match f1; -f1
421 [ /3 width=4 by coafter_isid_inv_dx, isfin_isid/ ]
422 #f2 #_ #IH #f1 #H #Hf1 #f #Hf
423 elim (at_inv_pxp … H) -H [ |*: // ] #g1 #H1
424 lapply (istot_inv_push … Hf1 … H1) -Hf1 #Hg1
425 elim (Hg1 (𝟏)) #n #Hn
426 [ elim (coafter_inv_ppx … Hf) | elim (coafter_inv_pnx … Hf)
427 ] -Hf [1,6: |*: // ] #g #Hg #H0 destruct
428 /5 width=6 by isfin_next, isfin_push, isfin_inv_tls, istot_tls, at_pxx_tls, coafter_tls_O/
431 fact coafter_isfin2_fwd_aux: (∀f1. @❪𝟏, f1❫ ≘ 𝟏 → H_coafter_isfin2_fwd f1) →
432 ∀i2,f1. @❪𝟏, f1❫ ≘ i2 → H_coafter_isfin2_fwd f1.
433 #H0 #i2 elim i2 -i2 /2 width=1 by/ -H0
434 #i2 #IH #f1 #H1f1 #f2 #Hf2 #H2f1 #f #Hf
435 elim (at_inv_pxn … H1f1) -H1f1 [ |*: // ] #g1 #Hg1 #H1
436 elim (coafter_inv_nxx … Hf … H1) -Hf #g #Hg #H0
437 lapply (IH … Hg1 … Hg) -i2 -Hg
438 /2 width=4 by istot_inv_next, isfin_push/ (**) (* full auto fails *)
441 lemma coafter_isfin2_fwd: ∀f1. H_coafter_isfin2_fwd f1.
442 #f1 #f2 #Hf2 #Hf1 cases (Hf1 (𝟏))
443 /3 width=7 by coafter_isfin2_fwd_aux, coafter_isfin2_fwd_O_aux/
446 lemma coafter_inv_sor: ∀f. 𝐅❪f❫ → ∀f2. 𝐓❪f2❫ → ∀f1. f2 ~⊚ f1 ≘ f → ∀fa,fb. fa ⋓ fb ≘ f →
447 ∃∃f1a,f1b. f2 ~⊚ f1a ≘ fa & f2 ~⊚ f1b ≘ fb & f1a ⋓ f1b ≘ f1.
449 [ #f #Hf #f2 #Hf2 #f1 #H1f #fa #fb #H2f
450 elim (sor_inv_isid3 … H2f) -H2f //
451 lapply (coafter_fwd_isid2 … H1f ??) -H1f //
452 /3 width=5 by ex3_2_intro, coafter_isid_dx, sor_isid/
453 | #f #_ #IH #f2 #Hf2 #f1 #H1 #fa #fb #H2
454 elim (sor_inv_xxp … H2) -H2 [ |*: // ] #ga #gb #H2f
455 elim (coafter_inv_xxp … H1) -H1 [1,3: * |*: // ] #g2 [ #g1 ] #H1f #Hgf2
456 [ lapply (istot_inv_push … Hf2 … Hgf2) | lapply (istot_inv_next … Hf2 … Hgf2) ] -Hf2 #Hg2
457 elim (IH … Hg2 … H1f … H2f) -f -Hg2
458 /3 width=11 by sor_pp, ex3_2_intro, coafter_refl, coafter_next/
459 | #f #_ #IH #f2 #Hf2 #f1 #H1 #fa #fb #H2
460 elim (coafter_inv_xxn … H1) -H1 [ |*: // ] #g2 #g1 #H1f #Hgf2
461 lapply (istot_inv_push … Hf2 … Hgf2) -Hf2 #Hg2
462 elim (sor_inv_xxn … H2) -H2 [1,3,4: * |*: // ] #ga #gb #H2f
463 elim (IH … Hg2 … H1f … H2f) -f -Hg2
464 /3 width=11 by sor_np, sor_pn, sor_nn, ex3_2_intro, coafter_refl, coafter_push/
468 (* Properties with istot ****************************************************)
470 lemma coafter_sor: ∀f. 𝐅❪f❫ → ∀f2. 𝐓❪f2❫ → ∀f1. f2 ~⊚ f1 ≘ f → ∀f1a,f1b. f1a ⋓ f1b ≘ f1 →
471 ∃∃fa,fb. f2 ~⊚ f1a ≘ fa & f2 ~⊚ f1b ≘ fb & fa ⋓ fb ≘ f.
473 [ #f #Hf #f2 #Hf2 #f1 #Hf #f1a #f1b #Hf1
474 lapply (coafter_fwd_isid2 … Hf ??) -Hf // #H2f1
475 elim (sor_inv_isid3 … Hf1) -Hf1 //
476 /3 width=5 by coafter_isid_dx, sor_idem, ex3_2_intro/
477 | #f #_ #IH #f2 #Hf2 #f1 #H1 #f1a #f1b #H2
478 elim (coafter_inv_xxp … H1) -H1 [1,3: * |*: // ]
479 [ #g2 #g1 #Hf #Hgf2 #Hgf1
480 elim (sor_inv_xxp … H2) -H2 [ |*: // ] #ga #gb #Hg1
481 lapply (istot_inv_push … Hf2 … Hgf2) -Hf2 #Hg2
482 elim (IH … Hf … Hg1) // -f1 -g1 -IH -Hg2
483 /3 width=11 by coafter_refl, sor_pp, ex3_2_intro/
485 lapply (istot_inv_next … Hf2 … Hgf2) -Hf2 #Hg2
486 elim (IH … Hf … H2) // -f1 -IH -Hg2
487 /3 width=11 by coafter_next, sor_pp, ex3_2_intro/
489 | #f #_ #IH #f2 #Hf2 #f1 #H1 #f1a #f1b #H2
490 elim (coafter_inv_xxn … H1) -H1 [ |*: // ] #g2 #g1 #Hf #Hgf2 #Hgf1
491 lapply (istot_inv_push … Hf2 … Hgf2) -Hf2 #Hg2
492 elim (sor_inv_xxn … H2) -H2 [1,3,4: * |*: // ] #ga #gb #Hg1
493 elim (IH … Hf … Hg1) // -f1 -g1 -IH -Hg2
494 /3 width=11 by coafter_refl, coafter_push, sor_np, sor_pn, sor_nn, ex3_2_intro/