]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/contribs/lambdadelta/ground/relocation/rtmap_coafter.ma
propagating the arithmetics library, partial commit
[helm.git] / matita / matita / contribs / lambdadelta / ground / relocation / rtmap_coafter.ma
1 (**************************************************************************)
2 (*       ___                                                              *)
3 (*      ||M||                                                             *)
4 (*      ||A||       A project by Andrea Asperti                           *)
5 (*      ||T||                                                             *)
6 (*      ||I||       Developers:                                           *)
7 (*      ||T||         The HELM team.                                      *)
8 (*      ||A||         http://helm.cs.unibo.it                             *)
9 (*      \   /                                                             *)
10 (*       \ /        This file is distributed under the terms of the       *)
11 (*        v         GNU General Public License Version 2                  *)
12 (*                                                                        *)
13 (**************************************************************************)
14
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".
19
20 (* RELOCATION MAP ***********************************************************)
21
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
29 .
30
31 interpretation "relational co-composition (rtmap)"
32    'RCoAfter f1 f2 f = (coafter f1 f2 f).
33
34 definition H_coafter_inj: predicate rtmap ≝
35                           λf1. 𝐓❪f1❫ →
36                           ∀f,f21,f22. f1 ~⊚ f21 ≘ f → f1 ~⊚ f22 ≘ f → f21 ≡ f22.
37
38 definition H_coafter_fwd_isid2: predicate rtmap ≝
39                                 λf1. ∀f2,f. f1 ~⊚ f2 ≘ f → 𝐓❪f1❫ → 𝐈❪f❫ → 𝐈❪f2❫.
40
41 definition H_coafter_isfin2_fwd: predicate rtmap ≝
42                                  λf1. ∀f2. 𝐅❪f2❫ → 𝐓❪f1❫ → ∀f. f1 ~⊚ f2 ≘ f →  𝐅❪f❫.
43
44 (* Basic inversion lemmas ***************************************************)
45
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)
56 ]
57 qed-.
58
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)
69 ]
70 qed-.
71
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/
82 ]
83 qed-.
84
85 (* Advanced inversion lemmas ************************************************)
86
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 //
92 qed-.
93
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)
99 qed-.
100
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 //
106 qed-.
107
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)
113 qed-.
114
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 //
120 qed-.
121
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)
127 qed-.
128
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)
135 ]
136 qed-.
137
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/
144 ]
145 qed-.
146
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)
152 ]
153 qed-.
154
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/
161 qed-.
162
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/
170 ]
171 qed-.
172
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/
181 ]
182 qed-.
183
184 (* Basic properties *********************************************************)
185
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/
192 ]
193 qed-.
194
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/
197 qed-.
198
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/
205 ]
206 qed-.
207
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/
210 qed-.
211
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/
218 ]
219 qed-.
220
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/
223 qed-.
224
225 (* Main inversion lemmas ****************************************************)
226
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/
233 ]
234 qed-.
235
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-.
239
240 (* Forward lemmas with pushs ************************************************)
241
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/
257     ]
258   ]
259 ]
260 qed-.
261
262 (* Inversion lemmas with tail ***********************************************)
263
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 *)
269 ]
270 qed-.
271
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 *)
277 ]
278 qed-.
279
280 (* Properties with iterated tail ********************************************)
281
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 //
294   ]
295 ]
296 qed.
297
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.
301
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 //
312 qed.
313 (*
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/
322 qed-.
323
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/
333 qed-.
334 *)
335 (* Properties with test for identity ****************************************)
336
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/
340 qed.
341
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/
346 ]
347 qed.
348
349 (* Inversion lemmas with test for identity **********************************)
350
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-.
353
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-.
356
357 (* Forward lemmas with istot ************************************************)
358
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
369 ]
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/
372 qed-.
373
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/
382 qed-.
383
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/
386 qed-.
387
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)
399 ]
400 qed-.
401
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 *)
409 qed-.
410
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/
414 qed-.
415
416 fact coafter_isfin2_fwd_O_aux: ∀f1. @❪𝟏, f1❫ ≘ 𝟏 →
417                                H_coafter_isfin2_fwd f1.
418 #f1 #Hf1 #f2 #H
419 generalize in match Hf1; generalize in match f1; -f1
420 @(isfin_ind … H) -f2
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/
429 qed-.
430
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 *)
439 qed-.
440
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/
444 qed-.
445
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.
448 @isfin_ind
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/
465 ]
466 qed-.
467
468 (* Properties with istot ****************************************************)
469
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.
472 @isfin_ind
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/
484   | #g2 #Hf #Hgf2
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/
488   ]
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/
495 ]
496 qed-.