1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| A.Asperti, C.Sacerdoti Coen, *)
8 (* ||A|| E.Tassi, S.Zacchiroli *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU Lesser General Public License Version 2.1 *)
13 (**************************************************************************)
15 include "nat/relevant_equations.ma".
16 include "nat/sigma_and_pi.ma".
17 include "nat/permutation.ma".
19 theorem sigma_f_g : \forall n,m:nat.\forall f,g:nat \to nat.
20 sigma n (\lambda p.f p + g p) m = sigma n f m + sigma n g m.
25 rewrite < (assoc_plus (g (S (n1+m)))).
26 rewrite > (sym_plus (g (S (n1+m)))).
27 rewrite > (assoc_plus (sigma n1 f m)).
32 theorem sigma_plus: \forall n,p,m:nat.\forall f:nat \to nat.
33 sigma (S (p+n)) f m = sigma p (\lambda x.(f ((S n) + x))) m + sigma n f m.
38 rewrite > assoc_plus in \vdash (? ? ? %).
42 rewrite > (sym_plus n).
44 rewrite < (sym_plus m).
45 rewrite < (assoc_plus n1).
49 theorem sigma_plus1: \forall n,p,m:nat.\forall f:nat \to nat.
50 sigma (p+(S n)) f m = sigma p (\lambda x.(f ((S n) + x))) m + sigma n f m.
54 rewrite > assoc_plus in \vdash (? ? ? %).
57 rewrite < plus_n_Sm.simplify.
58 rewrite < (sym_plus n).
60 rewrite < (sym_plus m).
61 rewrite < (assoc_plus n).
65 theorem eq_sigma_sigma : \forall n,m:nat.\forall f:nat \to nat.
66 sigma (pred ((S n)*(S m))) f O =
67 sigma m (\lambda a.(sigma n (\lambda b.f (b*(S m) + a)) O)) O.
68 intro.elim n.simplify.
70 apply eq_sigma.intros.reflexivity.
75 rewrite > (S_pred ((S n1)*(S m))).
77 simplify.unfold lt.apply le_S_S.apply le_O_n.
80 theorem eq_sigma_sigma1 : \forall n,m:nat.\forall f:nat \to nat.
81 sigma (pred ((S n)*(S m))) f O =
82 sigma n (\lambda a.(sigma m (\lambda b.f (b*(S n) + a)) O)) O.
88 theorem sigma_times: \forall n,m,p:nat.\forall f:nat \to nat.
89 (sigma n f m)*p = sigma n (\lambda i.(f i) * p) m.
90 intro. elim n.simplify.reflexivity.
95 definition bool_to_nat: bool \to nat \def
96 \lambda b. match b with
97 [ true \Rightarrow (S O)
98 | false \Rightarrow O ].
100 theorem bool_to_nat_andb: \forall a,b:bool.
101 bool_to_nat (andb a b) = (bool_to_nat a)*(bool_to_nat b).
102 intros. elim a.elim b.
103 simplify.reflexivity.
108 definition count : nat \to (nat \to bool) \to nat \def
109 \lambda n.\lambda f. sigma (pred n) (\lambda n.(bool_to_nat (f n))) O.
111 theorem count_times:\forall n,m:nat.
112 \forall f,f1,f2:nat \to bool.
113 \forall g:nat \to nat \to nat.
114 \forall g1,g2: nat \to nat.
115 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g b a) < (S n)*(S m)) \to
116 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g1 (g b a)) = a) \to
117 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g2 (g b a)) = b) \to
118 (\forall a,b:nat. a < (S n) \to b < (S m) \to f (g b a) = andb (f2 b) (f1 a)) \to
119 (count ((S n)*(S m)) f) = (count (S n) f1)*(count (S m) f2).
121 rewrite < eq_map_iter_i_sigma.
122 rewrite > (permut_to_eq_map_iter_i plus assoc_plus sym_plus ? ? ?
123 (\lambda i.g (div i (S n)) (mod i (S n)))).
124 rewrite > eq_map_iter_i_sigma.
125 rewrite > eq_sigma_sigma1.
128 sigma m (\lambda b.(bool_to_nat (f2 b))*(bool_to_nat (f1 a))) O) O)).
129 apply eq_sigma.intros.
130 apply eq_sigma.intros.
131 rewrite > (div_mod_spec_to_eq (i1*(S n) + i) (S n) ((i1*(S n) + i)/(S n))
132 ((i1*(S n) + i) \mod (S n)) i1 i).
133 rewrite > (div_mod_spec_to_eq2 (i1*(S n) + i) (S n) ((i1*(S n) + i)/(S n))
134 ((i1*(S n) + i) \mod (S n)) i1 i).
136 apply bool_to_nat_andb.
137 unfold lt.apply le_S_S.assumption.
138 unfold lt.apply le_S_S.assumption.
139 apply div_mod_spec_div_mod.
140 unfold lt.apply le_S_S.apply le_O_n.
141 constructor 1.unfold lt.apply le_S_S.assumption.
143 apply div_mod_spec_div_mod.
144 unfold lt.apply le_S_S.apply le_O_n.
145 constructor 1.unfold lt.apply le_S_S.assumption.
148 (sigma n (\lambda n.((bool_to_nat (f1 n)) *
149 (sigma m (\lambda n.bool_to_nat (f2 n)) O))) O)).
154 (sigma m (\lambda n.(bool_to_nat (f2 n))*(bool_to_nat (f1 i))) O)).
156 apply sym_eq. apply sigma_times.
158 apply sym_eq. apply sigma_times.
164 rewrite < S_pred in \vdash (? ? %).
165 change with ((g (i/(S n)) (i \mod (S n))) \lt (S n)*(S m)).
168 unfold lt. apply le_S_S.apply le_O_n.
169 apply (lt_times_to_lt_l n).
170 apply (le_to_lt_to_lt ? i).
171 rewrite > (div_mod i (S n)) in \vdash (? ? %).
174 unfold lt. apply le_S_S.apply le_O_n.
176 rewrite > S_pred in \vdash (? ? %).
178 rewrite > plus_n_O in \vdash (? ? %).
179 rewrite > sym_times. assumption.
180 rewrite > (times_n_O O).
182 unfold lt. apply le_S_S.apply le_O_n.
183 unfold lt. apply le_S_S.apply le_O_n.
184 rewrite > (times_n_O O).
186 unfold lt. apply le_S_S.apply le_O_n.
187 unfold lt. apply le_S_S.apply le_O_n.
191 cut (i < (S n)*(S m)).
192 cut (j < (S n)*(S m)).
193 cut ((i \mod (S n)) < (S n)).
194 cut ((i/(S n)) < (S m)).
195 cut ((j \mod (S n)) < (S n)).
196 cut ((j/(S n)) < (S m)).
197 rewrite > (div_mod i (S n)).
198 rewrite > (div_mod j (S n)).
199 rewrite < (H1 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3).
200 rewrite < (H2 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3) in \vdash (? ? (? % ?) ?).
201 rewrite < (H1 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5).
202 rewrite < (H2 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5) in \vdash (? ? ? (? % ?)).
203 rewrite > H6.reflexivity.
204 unfold lt. apply le_S_S.apply le_O_n.
205 unfold lt. apply le_S_S.apply le_O_n.
206 apply (lt_times_to_lt_l n).
207 apply (le_to_lt_to_lt ? j).
208 rewrite > (div_mod j (S n)) in \vdash (? ? %).
211 unfold lt. apply le_S_S.apply le_O_n.
212 rewrite < sym_times. assumption.
214 unfold lt. apply le_S_S.apply le_O_n.
215 apply (lt_times_to_lt_l n).
216 apply (le_to_lt_to_lt ? i).
217 rewrite > (div_mod i (S n)) in \vdash (? ? %).
220 unfold lt. apply le_S_S.apply le_O_n.
221 rewrite < sym_times. assumption.
223 unfold lt. apply le_S_S.apply le_O_n.
225 rewrite > S_pred in \vdash (? ? %).
226 apply le_S_S.assumption.
227 rewrite > (times_n_O O).
229 unfold lt. apply le_S_S.apply le_O_n.
230 unfold lt. apply le_S_S.apply le_O_n.
232 rewrite > S_pred in \vdash (? ? %).
233 apply le_S_S.assumption.
234 rewrite > (times_n_O O).
236 unfold lt. apply le_S_S.apply le_O_n.
237 unfold lt. apply le_S_S.apply le_O_n.
240 apply (not_le_Sn_O m1 H4).