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 set "baseuri" "cic:/matita/nat/count".
17 include "nat/relevant_equations.ma".
18 include "nat/sigma_and_pi.ma".
19 include "nat/permutation.ma".
21 theorem sigma_f_g : \forall n,m:nat.\forall f,g:nat \to nat.
22 sigma n (\lambda p.f p + g p) m = sigma n f m + sigma n g m.
27 rewrite < (assoc_plus (g (S (n1+m)))).
28 rewrite > (sym_plus (g (S (n1+m)))).
29 rewrite > (assoc_plus (sigma n1 f m)).
34 theorem sigma_plus: \forall n,p,m:nat.\forall f:nat \to nat.
35 sigma (S (p+n)) f m = sigma p (\lambda x.(f ((S n) + x))) m + sigma n f m.
38 rewrite < (sym_plus n m).reflexivity.
40 rewrite > assoc_plus in \vdash (? ? ? %).
44 rewrite > (sym_plus n).
46 rewrite < (sym_plus m).
47 rewrite < (assoc_plus n1).
51 theorem sigma_plus1: \forall n,p,m:nat.\forall f:nat \to nat.
52 sigma (p+(S n)) f m = sigma p (\lambda x.(f ((S n) + x))) m + sigma n f m.
56 rewrite > assoc_plus in \vdash (? ? ? %).
59 rewrite < plus_n_Sm.simplify.
60 rewrite < (sym_plus n).
62 rewrite < (sym_plus m).
63 rewrite < (assoc_plus n).
67 theorem eq_sigma_sigma : \forall n,m:nat.\forall f:nat \to nat.
68 sigma (pred ((S n)*(S m))) f O =
69 sigma m (\lambda a.(sigma n (\lambda b.f (b*(S m) + a)) O)) O.
70 intro.elim n.simplify.
72 apply eq_sigma.intros.reflexivity.
77 rewrite > (S_pred ((S n1)*(S m))).
79 simplify.unfold lt.apply le_S_S.apply le_O_n.
82 theorem eq_sigma_sigma1 : \forall n,m:nat.\forall f:nat \to nat.
83 sigma (pred ((S n)*(S m))) f O =
84 sigma n (\lambda a.(sigma m (\lambda b.f (b*(S n) + a)) O)) O.
90 theorem sigma_times: \forall n,m,p:nat.\forall f:nat \to nat.
91 (sigma n f m)*p = sigma n (\lambda i.(f i) * p) m.
92 intro. elim n.simplify.reflexivity.
97 definition bool_to_nat: bool \to nat \def
98 \lambda b. match b with
99 [ true \Rightarrow (S O)
100 | false \Rightarrow O ].
102 theorem bool_to_nat_andb: \forall a,b:bool.
103 bool_to_nat (andb a b) = (bool_to_nat a)*(bool_to_nat b).
104 intros. elim a.elim b.
105 simplify.reflexivity.
110 definition count : nat \to (nat \to bool) \to nat \def
111 \lambda n.\lambda f. sigma (pred n) (\lambda n.(bool_to_nat (f n))) O.
113 theorem count_times:\forall n,m:nat.
114 \forall f,f1,f2:nat \to bool.
115 \forall g:nat \to nat \to nat.
116 \forall g1,g2: nat \to nat.
117 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g b a) < (S n)*(S m)) \to
118 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g1 (g b a)) = a) \to
119 (\forall a,b:nat. a < (S n) \to b < (S m) \to (g2 (g b a)) = b) \to
120 (\forall a,b:nat. a < (S n) \to b < (S m) \to f (g b a) = andb (f2 b) (f1 a)) \to
121 (count ((S n)*(S m)) f) = (count (S n) f1)*(count (S m) f2).
123 rewrite < eq_map_iter_i_sigma.
124 rewrite > (permut_to_eq_map_iter_i plus assoc_plus sym_plus ? ? ?
125 (\lambda i.g (div i (S n)) (mod i (S n)))).
126 rewrite > eq_map_iter_i_sigma.
127 rewrite > eq_sigma_sigma1.
130 sigma m (\lambda b.(bool_to_nat (f2 b))*(bool_to_nat (f1 a))) O) O)).
131 apply eq_sigma.intros.
132 apply eq_sigma.intros.
133 rewrite > (div_mod_spec_to_eq (i1*(S n) + i) (S n) ((i1*(S n) + i)/(S n))
134 ((i1*(S n) + i) \mod (S n)) i1 i).
135 rewrite > (div_mod_spec_to_eq2 (i1*(S n) + i) (S n) ((i1*(S n) + i)/(S n))
136 ((i1*(S n) + i) \mod (S n)) i1 i).
138 apply bool_to_nat_andb.
139 unfold lt.apply le_S_S.assumption.
140 unfold lt.apply le_S_S.assumption.
141 apply div_mod_spec_div_mod.
142 unfold lt.apply le_S_S.apply le_O_n.
143 constructor 1.unfold lt.apply le_S_S.assumption.
145 apply div_mod_spec_div_mod.
146 unfold lt.apply le_S_S.apply le_O_n.
147 constructor 1.unfold lt.apply le_S_S.assumption.
150 (sigma n (\lambda n.((bool_to_nat (f1 n)) *
151 (sigma m (\lambda n.bool_to_nat (f2 n)) O))) O)).
156 (sigma m (\lambda n.(bool_to_nat (f2 n))*(bool_to_nat (f1 i))) O)).
158 apply sym_eq. apply sigma_times.
160 apply sym_eq. apply sigma_times.
166 rewrite < S_pred in \vdash (? ? %).
167 change with ((g (i/(S n)) (i \mod (S n))) \lt (S n)*(S m)).
170 unfold lt. apply le_S_S.apply le_O_n.
171 apply (lt_times_to_lt_l n).
172 apply (le_to_lt_to_lt ? i).
173 rewrite > (div_mod i (S n)) in \vdash (? ? %).
176 unfold lt. apply le_S_S.apply le_O_n.
178 rewrite > S_pred in \vdash (? ? %).
180 rewrite > plus_n_O in \vdash (? ? %).
181 rewrite > sym_times. assumption.
182 rewrite > (times_n_O O).
184 unfold lt. apply le_S_S.apply le_O_n.
185 unfold lt. apply le_S_S.apply le_O_n.
186 rewrite > (times_n_O O).
188 unfold lt. apply le_S_S.apply le_O_n.
189 unfold lt. apply le_S_S.apply le_O_n.
193 cut (i < (S n)*(S m)).
194 cut (j < (S n)*(S m)).
195 cut ((i \mod (S n)) < (S n)).
196 cut ((i/(S n)) < (S m)).
197 cut ((j \mod (S n)) < (S n)).
198 cut ((j/(S n)) < (S m)).
199 rewrite > (div_mod i (S n)).
200 rewrite > (div_mod j (S n)).
201 rewrite < (H1 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3).
202 rewrite < (H2 (i \mod (S n)) (i/(S n)) Hcut2 Hcut3) in \vdash (? ? (? % ?) ?).
203 rewrite < (H1 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5).
204 rewrite < (H2 (j \mod (S n)) (j/(S n)) Hcut4 Hcut5) in \vdash (? ? ? (? % ?)).
205 rewrite > H6.reflexivity.
206 unfold lt. apply le_S_S.apply le_O_n.
207 unfold lt. apply le_S_S.apply le_O_n.
208 apply (lt_times_to_lt_l n).
209 apply (le_to_lt_to_lt ? j).
210 rewrite > (div_mod j (S n)) in \vdash (? ? %).
213 unfold lt. apply le_S_S.apply le_O_n.
214 rewrite < sym_times. assumption.
216 unfold lt. apply le_S_S.apply le_O_n.
217 apply (lt_times_to_lt_l n).
218 apply (le_to_lt_to_lt ? i).
219 rewrite > (div_mod i (S n)) in \vdash (? ? %).
222 unfold lt. apply le_S_S.apply le_O_n.
223 rewrite < sym_times. assumption.
225 unfold lt. apply le_S_S.apply le_O_n.
227 rewrite > S_pred in \vdash (? ? %).
228 apply le_S_S.assumption.
229 rewrite > (times_n_O O).
231 unfold lt. apply le_S_S.apply le_O_n.
232 unfold lt. apply le_S_S.apply le_O_n.
234 rewrite > S_pred in \vdash (? ? %).
235 apply le_S_S.assumption.
236 rewrite > (times_n_O O).
238 unfold lt. apply le_S_S.apply le_O_n.
239 unfold lt. apply le_S_S.apply le_O_n.
242 apply (not_le_Sn_O m1 H4).