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 (**************************************************************************)
16 include "list/list.ma".
17 include "cprop_connectives.ma".
20 notation "\rationals" non associative with precedence 99 for @{'q}.
21 interpretation "Q" 'q = Q.
23 definition bar ≝ ratio × ℚ. (* base (Qpos) , height *)
24 record q_f : Type ≝ { start : ℚ; bars: list bar }.
28 axiom qlt : ℚ → ℚ → CProp.
30 interpretation "Q plus" 'plus x y = (qp x y).
31 interpretation "Q minus" 'minus x y = (qm x y).
32 interpretation "Q less than" 'lt x y = (qlt x y).
34 inductive q_comparison (a,b:ℚ) : CProp ≝
35 | q_eq : a = b → q_comparison a b
36 | q_lt : a < b → q_comparison a b
37 | q_gt : b < a → q_comparison a b.
39 axiom q_cmp:∀a,b:ℚ.q_comparison a b.
41 definition qle ≝ λa,b:ℚ.a = b ∨ a < b.
43 interpretation "Q less or equal than" 'leq x y = (qle x y).
45 axiom q_le_minus: ∀a,b,c:ℚ. a ≤ c - b → a + b ≤ c.
46 axiom q_lt_plus: ∀a,b,c:ℚ. a - b < c → a < c + b.
48 axiom dist : ℚ → ℚ → ℚ.
51 interpretation "list nth" 'nth = (nth _).
52 interpretation "list nth" 'nth_appl l d i = (nth _ l d i).
53 notation "'nth'" with precedence 90 for @{'nth}.
54 notation < "'nth' \nbsp term 90 l \nbsp term 90 d \nbsp term 90 i"
55 with precedence 69 for @{'nth_appl $l $d $i}.
57 notation < "\rationals \sup 2" non associative with precedence 90 for @{'q2}.
58 interpretation "Q x Q" 'q2 = (Prod Q Q).
60 definition make_list ≝
62 let rec make_list (n:nat) on n ≝
63 match n with [ O ⇒ nil ? | S m ⇒ def m :: make_list m]
66 interpretation "'mk_list' appl" 'mk_list_appl f n = (make_list _ f n).
67 interpretation "'mk_list'" 'mk_list = (make_list _).
68 notation "'mk_list'" with precedence 90 for @{'mk_list}.
69 notation < "'mk_list' \nbsp term 90 f \nbsp term 90 n"
70 with precedence 69 for @{'mk_list_appl $f $n}.
73 definition empty_bar : bar ≝ 〈one,OQ〉.
74 notation "\rect" with precedence 90 for @{'empty_bar}.
75 interpretation "q0" 'empty_bar = empty_bar.
77 notation < "\ldots\rect\square\EmptySmallSquare\ldots" with precedence 90 for @{'lq2}.
78 interpretation "lq2" 'lq2 = (list bar).
80 notation "'len'" with precedence 90 for @{'len}.
81 interpretation "len" 'len = (length _).
82 notation < "'len' \nbsp term 90 l" with precedence 69 for @{'len_appl $l}.
83 interpretation "len appl" 'len_appl l = (length _ l).
85 (* a local letin makes russell fail *)
86 definition cb0h ≝ (λl.mk_list (λi.〈\fst (nth l ▭ i),OQ〉) (len l)).
88 lemma len_mk_list : ∀T:Type.∀f:nat→T.∀n.len (mk_list f n) = n.
89 intros; elim n; [reflexivity] simplify; rewrite > H; reflexivity;
92 let rec sum_bases (l:list bar) (i:nat)on i ≝
97 [ nil ⇒ sum_bases l m + Qpos one
98 | cons x tl ⇒ sum_bases tl m + Qpos (\fst x)]].
101 λP.λp:∃x:nat × ℚ.P x.match p with [ex_introT p _ ⇒ p].
103 definition inject1 ≝ λP.λp:nat × ℚ.λh:P p. ex_introT ? P p h.
104 coercion inject1 with 0 1 nocomposites.
107 ∀f:q_f.∀i:ℚ.∃p:nat × ℚ.
108 match q_cmp i (start f) with
109 [ q_lt _ ⇒ \snd p = OQ
112 (sum_bases (bars f) (\fst p) ≤ i - start f)
113 (i - start f < sum_bases (bars f) (S (\fst p)))
114 (\snd p = \snd (nth (bars f) ▭ (\fst p)))].
116 alias symbol "pi2" = "pair pi2".
117 alias symbol "pi1" = "pair pi1".
119 let rec value (p: ℚ) (l : list bar) on l ≝
123 match q_cmp p (Qpos (\fst x)) with
124 [ q_lt _ ⇒ 〈O, \snd x〉
126 let rc ≝ value (p - Qpos (\fst x)) tl in
127 〈S (\fst rc),\snd rc〉]]
129 ∀acc,l.∃p:nat × ℚ. OQ ≤ acc →
131 (sum_bases l (\fst p) ≤ acc)
132 (acc < sum_bases l (S (\fst p)))
133 (\snd p = \snd (nth l ▭ (\fst p))));
135 cases (q_cmp i (start f));
136 [2: exists [apply 〈O,OQ〉] simplify; reflexivity;
137 |*: cases (value (i - start f) (bars f)) (p Hp);
138 cases Hp; clear Hp value;
139 exists[1,3:apply p]; simplify; split; assumption;]
141 [1,4: clear H2; cases (value (q-Qpos (\fst b)) l1); cases H2; clear H2;
142 simplify; apply q_le_minus; assumption;
143 |2,5: cases (value (q-Qpos (\fst b)) l1); cases H3; clear H3 H2 value;
144 change with (q < sum_bases l1 (S (\fst w)) + Qpos (\fst b));
145 apply q_lt_plus; assumption;
146 |*: cases (value (q-Qpos (\fst b)) l1); simplify; cases H3; clear H3 value H2;
148 |2: clear value H2; simplify; split;
152 definition same_shape ≝
157 (sum_bases (bars l2) j ≤ offset - start l2)
158 (offset - start l2 ≤ sum_bases (bars l2) (S j))
159 (\snd (nth (bars l2)) q0 j) = \snd (nth (bars l1) q0 i).
162 \ldots\boxdl\boxh\boxdr\boxdl\ldots
164 alias symbol "pi2" = "pair pi2".
165 alias symbol "pi1" = "pair pi1".
166 definition rebase_spec ≝
167 ∀l1,l2:q_f.∃p:q_f × q_f.
169 (len (bars (\fst p)) = len (bars (\snd p)))
170 (start (\fst p) = start (\snd p))
171 (∀i.\fst (nth (bars (\fst p)) q0 i) = \fst (nth (bars (\snd p)) q0 i))
173 sum_bases (bars l1) i ≤ offset - start l1 →
174 offset - start l1 ≤ sum_bases (bars l1) (S i) →
177 (sum_bases (bars (\fst p)) j ≤ offset - start (\fst p))
178 (offset - start (\fst p) ≤ sum_bases (bars (\fst p)) (S j))
179 (\snd (nth (bars (\fst p)) q0 j) = \snd (nth (bars l1) q0 i)) ∧
181 (sum_bases (bars (\snd p)) j ≤ offset - start (\snd p))
182 (offset - start (\snd p) ≤ sum_bases (bars (\snd p)) (S j))
183 (\snd (nth (bars (\snd p)) q0 j) = \snd (nth (bars l2) q0 i))).
185 definition rebase_spec_simpl ≝
186 λl1,l2:list (ℚ × ℚ).λp:(list (ℚ × ℚ)) × (list (ℚ × ℚ)).
187 len ( (\fst p)) = len ( (\snd p)) ∧
189 \fst (nth ( (\fst p)) q0 i) =
190 \fst (nth ( (\snd p)) q0 i)) ∧
192 sum_bases ( l1) i ≤ offset ∧
193 offset ≤ sum_bases ( l1) (S i)
196 sum_bases ( (\fst p)) j ≤ offset ∧
197 offset ≤ sum_bases ((\fst p)) (S j) ∧
198 \snd (nth ( (\fst p)) q0 j) =
199 \snd (nth ( l1) q0 i).
202 λP.λp:∃x:(list bar) × (list bar).P x.match p with [ex_introT p _ ⇒ p].
204 definition inject ≝ λP.λp:(list bar) × (list bar).λh:P p. ex_introT ? P p h.
205 coercion inject with 0 1 nocomposites.
207 definition rebase: rebase_spec.
208 intros 2 (f1 f2); cases f1 (s1 l1); cases f2 (s2 l2); clear f1 f2;
210 λl1,l2:list (ℚ × ℚ).λm:nat.λz:(list (ℚ × ℚ)) × (list (ℚ × ℚ)).
211 len l1 + len l2 < m → rebase_spec_simpl l1 l2 z);
213 let rec aux (l1,l2:list (ℚ × ℚ)) (n:nat) on n : (list (ℚ × ℚ)) × (list (ℚ × ℚ)) ≝
215 [ O ⇒ 〈 nil ? , nil ? 〉
218 [ nil ⇒ 〈cb0h l2, l2〉
221 [ nil ⇒ 〈l1, cb0h l1〉
223 let base1 ≝ (\fst he1) in
224 let base2 ≝ (\fst he2) in
225 let height1 ≝ (\snd he1) in
226 let height2 ≝ (\snd he2) in
227 match q_cmp base1 base2 with
229 let rc ≝ aux tl1 tl2 m in
230 〈he1 :: \fst rc,he2 :: \snd rc〉
232 let rest ≝ base2 - base1 in
233 let rc ≝ aux tl1 (〈rest,height2〉 :: tl2) m in
234 〈〈base1,height1〉 :: \fst rc,〈base1,height2〉 :: \snd rc〉
236 let rest ≝ base1 - base2 in
237 let rc ≝ aux (〈rest,height1〉 :: tl1) tl2 m in
238 〈〈base2,height1〉 :: \fst rc,〈base2,height2〉 :: \snd rc〉
240 in aux : ∀l1,l2,m.∃z.spec l1 l2 m z); unfold spec;
241 [7: clearbody aux; unfold spec in aux; clear spec;
243 [1: cases (aux l1 l2 (S (len l1 + len l2)));
244 cases (H1 (le_n ?)); clear H1;
245 exists [apply 〈mk_q_f s1 (\fst w), mk_q_f s2 (\snd w)〉] repeat split;
246 [1: cases H2; assumption;
248 |3: cases H2; assumption;
249 |4: intros; cases (H3 i (offset - s1));
253 |1,2: simplify; generalize in ⊢ (? ? (? (? ? (? ? ? (? ? %)))) (? (? ? (? ? ? (? ? %))))); intro X;
254 cases X (rc OK); clear X; simplify; apply eq_f; assumption;
255 |3: cases (aux l4 l5 n1) (rc OK); simplify; apply eq_f; assumption;
256 |4,5: simplify; unfold cb0h; rewrite > len_mk_list; reflexivity;
258 clearbody aux; unfold spec in aux; clear spec;