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 (**************************************************************************)
15 (* ********************************************************************** *)
16 (* Progetto FreeScale *)
18 (* Sviluppato da: Ing. Cosimo Oliboni, oliboni@cs.unibo.it *)
19 (* Ultima modifica: 05/08/2009 *)
21 (* ********************************************************************** *)
23 include "common/list.ma".
24 include "common/nat_lemmas.ma".
25 include "common/prod.ma".
27 nlet rec nmember_natList (elem:nat) (l:ne_list nat) on l ≝
29 [ ne_nil h ⇒ ⊖(eq_nat elem h)
30 | ne_cons h t ⇒ match eq_nat elem h with
31 [ true ⇒ false | false ⇒ nmember_natList elem t ]
34 (* elem presente una ed una sola volta in l *)
35 nlet rec member_natList (elem:nat) (l:ne_list nat) on l ≝
37 [ ne_nil h ⇒ eq_nat elem h
38 | ne_cons h t ⇒ match eq_nat elem h with
39 [ true ⇒ nmember_natList elem t | false ⇒ member_natList elem t ]
42 (* costruttore di un sottouniverso:
43 S_EL cioe' uno qualsiasi degli elementi del sottouniverso
45 ninductive S_UN (l:ne_list nat) : Type ≝
46 S_EL : Πx:nat.((member_natList x l) = true) → S_UN l.
48 ndefinition getelem : ∀l.∀e:S_UN l.nat.
54 ndefinition eq_SUN ≝ λl.λx,y:S_UN l.eq_nat (getelem ? x) (getelem ? y).
56 ndefinition getdim : ∀l.∀e:S_UN l.member_natList (getelem ? e) l = true.
63 : ∀l.∀e1,e2.∀dim1,dim2.S_EL l e1 dim1 = S_EL l e2 dim2 → e1 = e2.
64 #l; #e1; #e2; #dim1; #dim2; #H;
65 nchange with (match S_EL l e2 dim2 with [ S_EL a _ ⇒ e1 = a ]);
71 (* destruct universale *)
72 ndefinition SUN_destruct : ∀l.∀x,y:S_UN l.∀P:Prop.x = y → match eq_SUN l x y with [ true ⇒ P → P | false ⇒ P ].
78 nchange with (? → (match eq_nat u1 u2 with [ true ⇒ P → P | false ⇒ P ]));
80 nrewrite > (SUN_destruct_1 l … H);
81 nrewrite > (eq_to_eqnat u2 u2 (refl_eq …));
86 (* eq_to_eqxx universale *)
87 nlemma eq_to_eqSUN : ∀l.∀x,y:S_UN l.x = y → eq_SUN l x y = true.
92 nchange with (? → eq_nat u1 u2 = true);
93 #H; napply (eq_to_eqnat u1 u2);
94 napply (SUN_destruct_1 l … H).
97 (* neqxx_to_neq universale *)
98 nlemma neqSUN_to_neq : ∀l.∀x,y:S_UN l.eq_SUN l x y = false → x ≠ y.
100 napply (not_to_not (n1 = n2) (eq_SUN l n1 n2 = true) …);
101 ##[ ##1: napply (eq_to_eqSUN l n1 n2)
102 ##| ##2: napply (eqfalse_to_neqtrue … H)
106 (* eqxx_to_eq universale *)
107 (* serve l'assioma di equivalenza sulle dimostrazioni *)
109 naxiom eqSUN_to_eq_aux : ∀l,e.∀dim1,dim2:((member_natList e l) = true).S_EL l e dim1 = S_EL l e dim2.
110 (* mi dice matita/logic/equality/eq.ind not found che e' vero perche' uso il mio...
111 #l; #e; #dim1; #dim2;
115 nlemma eqSUN_to_eq : ∀l.∀x,y:S_UN l.eq_SUN l x y = true → x = y.
120 nchange with ((eq_nat u1 u2 = true) → ?);
122 nrewrite > (eqnat_to_eq u1 u2 H) in dim1:(%) ⊢ %;
124 napply eqSUN_to_eq_aux.
127 (* neq_to_neqxx universale *)
128 nlemma neq_to_neqSUN : ∀l.∀x,y:S_UN l.x ≠ y → eq_SUN l x y = false.
130 napply (neqtrue_to_eqfalse (eq_SUN l n1 n2));
131 napply (not_to_not (eq_SUN l n1 n2 = true) (n1 = n2) ? H);
132 napply (eqSUN_to_eq l n1 n2).
135 (* decidibilita' universale *)
136 nlemma decidable_SUN : ∀l.∀x,y:S_UN l.decidable (x = y).
137 #l; #x; #y; nnormalize;
138 napply (or2_elim (eq_SUN l x y = true) (eq_SUN l x y = false) ? (decidable_bexpr ?));
139 ##[ ##1: #H; napply (or2_intro1 (x = y) (x ≠ y) (eqSUN_to_eq l … H))
140 ##| ##2: #H; napply (or2_intro2 (x = y) (x ≠ y) (neqSUN_to_neq l … H))
144 (* simmetria di uguaglianza universale *)
145 nlemma symmetric_eqSUN : ∀l.symmetricT (S_UN l) bool (eq_SUN l).
147 napply (or2_elim (n1 = n2) (n1 ≠ n2) ? (decidable_SUN l n1 n2));
148 ##[ ##1: #H; nrewrite > H; napply refl_eq
149 ##| ##2: #H; nrewrite > (neq_to_neqSUN l n1 n2 H);
150 napply (symmetric_eq ? (eq_SUN l n2 n1) false);
151 napply (neq_to_neqSUN l n2 n1 (symmetric_neq ? n1 n2 H))
155 (* scheletro di funzione generica ad 1 argomento *)
156 nlet rec farg1_auxT (T:Type) (l:ne_list nat) on l ≝
159 | ne_cons _ t ⇒ ProdT T (farg1_auxT T t)
162 nlemma farg1_auxDim : ∀h,t,x.eq_nat x h = false → member_natList x (h§§t) = true → member_natList x t = true.
164 nnormalize in H1:(%);
165 nrewrite > H in H1:(%);
170 nlet rec farg1 (T:Type) (l:ne_list nat) on l ≝
172 [ ne_nil h ⇒ λarg:farg1_auxT T «£h».λx:S_UN «£h».arg
173 | ne_cons h t ⇒ λarg:farg1_auxT T (h§§t).λx:S_UN (h§§t).
174 match eq_nat (getelem ? x) h
175 return λy.eq_nat (getelem ? x) h = y → ?
177 [ true ⇒ λp:(eq_nat (getelem ? x) h = true).fst … arg
178 | false ⇒ λp:(eq_nat (getelem ? x) h = false).
181 (S_EL t (getelem ? x) (farg1_auxDim h t (getelem ? x) p (getdim ? x)))
182 ] (refl_eq ? (eq_nat (getelem ? x) h))
185 (* scheletro di funzione generica a 2 argomenti *)
186 nlet rec farg2 (T:Type) (l,lfix:ne_list nat) on l ≝
188 [ ne_nil h ⇒ λarg:farg1_auxT (farg1_auxT T lfix) «£h».λx:S_UN «£h».farg1 T lfix arg
189 | ne_cons h t ⇒ λarg:farg1_auxT (farg1_auxT T lfix) (h§§t).λx:S_UN (h§§t).
190 match eq_nat (getelem ? x) h
191 return λy.eq_nat (getelem ? x) h = y → ?
193 [ true ⇒ λp:(eq_nat (getelem ? x) h = true).farg1 T lfix (fst … arg)
194 | false ⇒ λp:(eq_nat (getelem ? x) h = false).
197 (S_EL t (getelem ? x) (farg1_auxDim h t (getelem ? x) p (getdim ? x)))
198 ] (refl_eq ? (eq_nat (getelem ? x) h))
201 (* esempio0: universo ottale *)
202 ndefinition oct0 ≝ O.
203 ndefinition oct1 ≝ S O.
204 ndefinition oct2 ≝ S (S O).
205 ndefinition oct3 ≝ S (S (S O)).
206 ndefinition oct4 ≝ S (S (S (S O))).
207 ndefinition oct5 ≝ S (S (S (S (S O)))).
208 ndefinition oct6 ≝ S (S (S (S (S (S O))))).
209 ndefinition oct7 ≝ S (S (S (S (S (S (S O)))))).
211 ndefinition oct_UN ≝ « oct0 ; oct1 ; oct2 ; oct3 ; oct4 ; oct5 ; oct6 £ oct7 ».
213 ndefinition uoct0 ≝ S_EL oct_UN oct0 (refl_eq …).
214 ndefinition uoct1 ≝ S_EL oct_UN oct1 (refl_eq …).
215 ndefinition uoct2 ≝ S_EL oct_UN oct2 (refl_eq …).
216 ndefinition uoct3 ≝ S_EL oct_UN oct3 (refl_eq …).
217 ndefinition uoct4 ≝ S_EL oct_UN oct4 (refl_eq …).
218 ndefinition uoct5 ≝ S_EL oct_UN oct5 (refl_eq …).
219 ndefinition uoct6 ≝ S_EL oct_UN oct6 (refl_eq …).
220 ndefinition uoct7 ≝ S_EL oct_UN oct7 (refl_eq …).
222 (* esempio1: NOT ottale *)
224 farg1 (S_UN oct_UN) oct_UN
225 (pair … uoct7 (pair … uoct6 (pair … uoct5 (pair … uoct4 (pair … uoct3 (pair … uoct2 (pair … uoct1 uoct0))))))).
227 (* esempio2: AND ottale *)
228 ndefinition octAND0 ≝ pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct0 uoct0)))))).
229 ndefinition octAND1 ≝ pair … uoct0 (pair … uoct1 (pair … uoct0 (pair … uoct1 (pair … uoct0 (pair … uoct1 (pair … uoct0 uoct1)))))).
230 ndefinition octAND2 ≝ pair … uoct0 (pair … uoct0 (pair … uoct2 (pair … uoct2 (pair … uoct0 (pair … uoct0 (pair … uoct2 uoct2)))))).
231 ndefinition octAND3 ≝ pair … uoct0 (pair … uoct1 (pair … uoct2 (pair … uoct3 (pair … uoct0 (pair … uoct1 (pair … uoct2 uoct3)))))).
232 ndefinition octAND4 ≝ pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct0 (pair … uoct4 (pair … uoct4 (pair … uoct4 uoct4)))))).
233 ndefinition octAND5 ≝ pair … uoct0 (pair … uoct1 (pair … uoct0 (pair … uoct1 (pair … uoct4 (pair … uoct5 (pair … uoct4 uoct5)))))).
234 ndefinition octAND6 ≝ pair … uoct0 (pair … uoct0 (pair … uoct2 (pair … uoct2 (pair … uoct4 (pair … uoct4 (pair … uoct6 uoct6)))))).
235 ndefinition octAND7 ≝ pair … uoct0 (pair … uoct1 (pair … uoct2 (pair … uoct3 (pair … uoct4 (pair … uoct5 (pair … uoct6 uoct7)))))).
238 farg2 (S_UN oct_UN) oct_UN oct_UN
239 (pair … octAND0 (pair … octAND1 (pair … octAND2 (pair … octAND3 (pair … octAND4 (pair … octAND5 (pair … octAND6 octAND7))))))).
241 (* ora e' possibile fare