1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.tcs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 include "ground_2/notation/relations/rat_3.ma".
16 include "ground_2/relocation/rtmap_id.ma".
18 (* RELOCATION MAP ***********************************************************)
20 coinductive at: rtmap → relation nat ≝
21 | at_refl: ∀f,g,j1,j2. ↑f = g → 0 = j1 → 0 = j2 → at g j1 j2
22 | at_push: ∀f,i1,i2. at f i1 i2 → ∀g,j1,j2. ↑f = g → ⫯i1 = j1 → ⫯i2 = j2 → at g j1 j2
23 | at_next: ∀f,i1,i2. at f i1 i2 → ∀g,j2. ⫯f = g → ⫯i2 = j2 → at g i1 j2
26 interpretation "relational application (rtmap)"
27 'RAt i1 f i2 = (at f i1 i2).
29 (* Basic inversion lemmas ***************************************************)
31 lemma at_inv_ppx: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g. 0 = i1 → ↑g = f → 0 = i2.
32 #f #i1 #i2 * -f -i1 -i2 //
33 [ #f #i1 #i2 #_ #g #j1 #j2 #_ * #_ #x #H destruct
34 | #f #i1 #i2 #_ #g #j2 * #_ #x #_ #H elim (discr_push_next … H)
38 lemma at_inv_npx: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g,j1. ⫯j1 = i1 → ↑g = f →
39 ∃∃j2. @⦃j1, g⦄ ≡ j2 & ⫯j2 = i2.
40 #f #i1 #i2 * -f -i1 -i2
41 [ #f #g #j1 #j2 #_ * #_ #x #x1 #H destruct
42 | #f #i1 #i2 #Hi #g #j1 #j2 * * * #x #x1 #H #Hf >(injective_push … Hf) -g destruct /2 width=3 by ex2_intro/
43 | #f #i1 #i2 #_ #g #j2 * #_ #x #x1 #_ #H elim (discr_push_next … H)
47 lemma at_inv_xnx: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g. ⫯g = f →
48 ∃∃j2. @⦃i1, g⦄ ≡ j2 & ⫯j2 = i2.
49 #f #i1 #i2 * -f -i1 -i2
50 [ #f #g #j1 #j2 * #_ #_ #x #H elim (discr_next_push … H)
51 | #f #i1 #i2 #_ #g #j1 #j2 * #_ #_ #x #H elim (discr_next_push … H)
52 | #f #i1 #i2 #Hi #g #j2 * * #x #H >(injective_next … H) -g /2 width=3 by ex2_intro/
56 (* Advanced inversion lemmas ************************************************)
58 lemma at_inv_ppn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
59 ∀g,j2. 0 = i1 → ↑g = f → ⫯j2 = i2 → ⊥.
60 #f #i1 #i2 #Hf #g #j2 #H1 #H <(at_inv_ppx … Hf … H1 H) -f -g -i1 -i2
64 lemma at_inv_npn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
65 ∀g,j1,j2. ⫯j1 = i1 → ↑g = f → ⫯j2 = i2 → @⦃j1, g⦄ ≡ j2.
66 #f #i1 #i2 #Hf #g #j1 #j2 #H1 #H elim (at_inv_npx … Hf … H1 H) -f -i1
67 #x2 #Hg * -i2 #H destruct //
70 lemma at_inv_npp: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
71 ∀g,j1. ⫯j1 = i1 → ↑g = f → 0 = i2 → ⊥.
72 #f #i1 #i2 #Hf #g #j1 #H1 #H elim (at_inv_npx … Hf … H1 H) -f -i1
73 #x2 #Hg * -i2 #H destruct
76 lemma at_inv_xnn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
77 ∀g,j2. ⫯g = f → ⫯j2 = i2 → @⦃i1, g⦄ ≡ j2.
78 #f #i1 #i2 #Hf #g #j2 #H elim (at_inv_xnx … Hf … H) -f
79 #x2 #Hg * -i2 #H destruct //
82 lemma at_inv_pxn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀j2. 0 = i1 → ⫯j2 = i2 →
83 ∃∃g. @⦃i1, g⦄ ≡ j2 & ⫯g = f.
84 #f elim (pn_split … f) *
85 #g #H #i1 #i2 #Hf #j2 #H1 #H2
86 [ elim (at_inv_ppn … Hf … H1 H H2)
87 | /3 width=5 by at_inv_xnn, ex2_intro/
91 lemma at_inv_xnp: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
92 ∀g. ⫯g = f → 0 = i2 → ⊥.
93 #f #i1 #i2 #Hf #g #H elim (at_inv_xnx … Hf … H) -f
94 #x2 #Hg * -i2 #H destruct
97 lemma at_inv_nxp: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 →
98 ∀j1. ⫯j1 = i1 → 0 = i2 → ⊥.
99 #f elim (pn_split f) *
100 #g #H #i1 #i2 #Hf #j1 #H1 #H2
101 [ elim (at_inv_npp … Hf … H1 H H2)
102 | elim (at_inv_xnp … Hf … H H2)
106 lemma at_inv_nxn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀j1,j2. ⫯j1 = i1 → ⫯j2 = i2 →
107 (∃∃g. @⦃j1, g⦄ ≡ j2 & ↑g = f) ∨
108 ∃∃g. @⦃i1, g⦄ ≡ j2 & ⫯g = f.
109 #f elim (pn_split f) *
110 /4 width=7 by at_inv_xnn, at_inv_npn, ex2_intro, or_intror, or_introl/
113 lemma at_inv_xpx: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g. ↑g = f →
115 ∃∃j1,j2. @⦃j1, g⦄ ≡ j2 & ⫯j1 = i1 & ⫯j2 = i2.
116 #f * [2: #i1 ] #i2 #Hf #g #H
117 [ elim (at_inv_npx … Hf … H) -f /3 width=5 by or_intror, ex3_2_intro/
118 | >(at_inv_ppx … Hf … H) -f /3 width=1 by conj, or_introl/
122 lemma at_inv_xpp: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g. ↑g = f → 0 = i2 → 0 = i1.
123 #f #i1 #i2 #Hf #g #H elim (at_inv_xpx … Hf … H) -f * //
124 #j1 #j2 #_ #_ * -i2 #H destruct
127 lemma at_inv_xpn: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → ∀g,j2. ↑g = f → ⫯j2 = i2 →
128 ∃∃j1. @⦃j1, g⦄ ≡ j2 & ⫯j1 = i1.
129 #f #i1 #i2 #Hf #g #j2 #H elim (at_inv_xpx … Hf … H) -f *
130 [ #_ * -i2 #H destruct
131 | #x1 #x2 #Hg #H1 * -i2 #H destruct /2 width=3 by ex2_intro/
135 lemma at_inv_xxp: ∀f,i1,i2. @⦃i1, f⦄ ≡ i2 → 0 = i2 →
136 ∃∃g. 0 = i1 & ↑g = f.
137 #f elim (pn_split f) *
138 #g #H #i1 #i2 #Hf #H2
139 [ /3 width=6 by at_inv_xpp, ex2_intro/
140 | elim (at_inv_xnp … Hf … H H2)
144 (* Basic forward lemmas *****************************************************)
146 lemma at_increasing: ∀i2,i1,f. @⦃i1, f⦄ ≡ i2 → i1 ≤ i2.
148 [ #i1 #f #Hf elim (at_inv_xxp … Hf) -Hf //
150 #i1 #f #Hf elim (at_inv_nxn … Hf) -Hf [1,4: * |*: // ]
151 /3 width=2 by le_S_S, le_S/
155 lemma at_increasing_strict: ∀g,i1,i2. @⦃i1, g⦄ ≡ i2 → ∀f. ⫯f = g →
156 i1 < i2 ∧ @⦃i1, f⦄ ≡ ⫰i2.
157 #g #i1 #i2 #Hg #f #H elim (at_inv_xnx … Hg … H) -Hg -H
158 /4 width=2 by conj, at_increasing, le_S_S/
161 lemma at_fwd_id_ex: ∀f,i. @⦃i, f⦄ ≡ i → ∃g. ↑g = f.
162 #f elim (pn_split f) * /2 width=2 by ex_intro/
163 #g #H #i #Hf elim (at_inv_xnx … Hf … H) -Hf -H
164 #j2 #Hg #H destruct lapply (at_increasing … Hg) -Hg
165 #H elim (lt_le_false … H) -H //
168 (* Basic properties *********************************************************)
170 let corec at_eq_repl_back: ∀i1,i2. eq_repl_back (λf. @⦃i1, f⦄ ≡ i2) ≝ ?.
171 #i1 #i2 #f1 #H1 cases H1 -f1 -i1 -i2
172 [ #f1 #g1 #j1 #j2 #H #H1 #H2 #f2 #H12 cases (eq_inv_px … H12 … H) -g1 /2 width=2 by at_refl/
173 | #f1 #i1 #i2 #Hf1 #g1 #j1 #j2 #H #H1 #H2 #f2 #H12 cases (eq_inv_px … H12 … H) -g1 /3 width=7 by at_push/
174 | #f1 #i1 #i2 #Hf1 #g1 #j2 #H #H2 #f2 #H12 cases (eq_inv_nx … H12 … H) -g1 /3 width=5 by at_next/
178 lemma at_eq_repl_fwd: ∀i1,i2. eq_repl_fwd (λf. @⦃i1, f⦄ ≡ i2).
179 #i1 #i2 @eq_repl_sym /2 width=3 by at_eq_repl_back/
182 lemma at_id_le: ∀i1,i2. i1 ≤ i2 → ∀f. @⦃i2, f⦄ ≡ i2 → @⦃i1, f⦄ ≡ i1.
183 #i1 #i2 #H @(le_elim … H) -i1 -i2 [ #i2 | #i1 #i2 #IH ]
184 #f #Hf elim (at_fwd_id_ex … Hf) /4 width=7 by at_inv_npn, at_push, at_refl/
187 (* Main properties **********************************************************)
189 theorem at_monotonic: ∀j2,i2,f2. @⦃i2, f2⦄ ≡ j2 → ∀j1,i1,f1. @⦃i1, f1⦄ ≡ j1 →
190 f1 ≗ f2 → i1 < i2 → j1 < j2.
192 [ #i2 #f2 #Hf2 elim (at_inv_xxp … Hf2) -Hf2 //
193 #g #H21 #_ #j1 #i1 #f1 #_ #_ #Hi elim (lt_le_false … Hi) -Hi //
194 | #j2 #IH #i2 #f2 #Hf2 * //
195 #j1 #i1 #f1 #Hf1 #Hf #Hi elim (lt_inv_gen … Hi)
196 #x2 #_ #H21 elim (at_inv_nxn … Hf2 … H21) -Hf2 [1,3: * |*: // ]
198 [ elim (eq_inv_xp … Hf … H2) -f2
199 #g1 #Hg #H1 elim (at_inv_xpn … Hf1 … H1) -f1
200 /4 width=8 by lt_S_S_to_lt, lt_S_S/
201 | elim (eq_inv_xn … Hf … H2) -f2
202 /4 width=8 by at_inv_xnn, lt_S_S/
207 theorem at_inv_monotonic: ∀j1,i1,f1. @⦃i1, f1⦄ ≡ j1 → ∀j2,i2,f2. @⦃i2, f2⦄ ≡ j2 →
208 f1 ≗ f2 → j1 < j2 → i1 < i2.
210 [ #i1 #f1 #Hf1 elim (at_inv_xxp … Hf1) -Hf1 //
211 #g1 * -i1 #H1 #j2 #i2 #f2 #Hf2 #Hf #Hj elim (lt_inv_O1 … Hj) -Hj
212 #x2 #H22 elim (eq_inv_px … Hf … H1) -f1
213 #g2 #Hg #H2 elim (at_inv_xpn … Hf2 … H2 H22) -f2 //
215 [ #f1 #Hf1 elim (at_inv_pxn … Hf1) -Hf1 [ |*: // ]
216 #g1 #Hg1 #H1 #j2 #i2 #f2 #Hf2 #Hf #Hj elim (lt_inv_S1 … Hj) -Hj
217 elim (eq_inv_nx … Hf … H1) -f1 /3 width=7 by at_inv_xnn/
218 | #i1 #f1 #Hf1 #j2 #i2 #f2 #Hf2 #Hf #Hj elim (lt_inv_S1 … Hj) -Hj
219 #y2 #Hj #H22 elim (at_inv_nxn … Hf1) -Hf1 [1,4: * |*: // ]
221 [ elim (eq_inv_px … Hf … H1) -f1
222 #g2 #Hg #H2 elim (at_inv_xpn … Hf2 … H2 H22) -f2 -H22
223 /3 width=7 by lt_S_S/
224 | elim (eq_inv_nx … Hf … H1) -f1 /3 width=7 by at_inv_xnn/
230 theorem at_mono: ∀f1,f2. f1 ≗ f2 → ∀i,i1. @⦃i, f1⦄ ≡ i1 → ∀i2. @⦃i, f2⦄ ≡ i2 → i2 = i1.
231 #f1 #f2 #Ht #i #i1 #H1 #i2 #H2 elim (lt_or_eq_or_gt i2 i1) //
232 #Hi elim (lt_le_false i i) /3 width=8 by at_inv_monotonic, eq_sym/
235 theorem at_inj: ∀f1,f2. f1 ≗ f2 → ∀i1,i. @⦃i1, f1⦄ ≡ i → ∀i2. @⦃i2, f2⦄ ≡ i → i1 = i2.
236 #f1 #f2 #Ht #i1 #i #H1 #i2 #H2 elim (lt_or_eq_or_gt i2 i1) //
237 #Hi elim (lt_le_false i i) /3 width=8 by at_monotonic, eq_sym/
240 (* Advanced inversion lemmas on isid ****************************************)
242 lemma isid_inv_at: ∀i,f. 𝐈⦃f⦄ → @⦃i, f⦄ ≡ i.
244 [ #f #H elim (isid_inv_gen … H) -H /2 width=2 by at_refl/
245 | #i #IH #f #H elim (isid_inv_gen … H) -H /3 width=7 by at_push/
249 lemma isid_inv_at_mono: ∀f,i1,i2. 𝐈⦃f⦄ → @⦃i1, f⦄ ≡ i2 → i1 = i2.
250 /3 width=6 by isid_inv_at, at_mono/ qed-.
252 (* Advancedd properties on isid *********************************************)
254 let corec isid_at: ∀f. (∀i. @⦃i, f⦄ ≡ i) → 𝐈⦃f⦄ ≝ ?.
256 #H cases (at_fwd_id_ex … H) -H
257 #g #H @(isid_push … H) /3 width=7 by at_inv_npn/
260 (* Advanced properties on id ************************************************)
262 lemma id_inv_at: ∀f. (∀i. @⦃i, f⦄ ≡ i) → 𝐈𝐝 ≗ f.
263 /3 width=1 by isid_at, eq_id_inv_isid/ qed-.
265 lemma id_at: ∀i. @⦃i, 𝐈𝐝⦄ ≡ i.
266 /2 width=1 by isid_inv_at/ qed.