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 include "projdat/coerc.ma".
17 (**************************************************************************)
18 (* Definizione di alcuni lemmi sulle liste *)
19 (**************************************************************************)
20 lemma list_tail: ∀A:DeqSet. ∀a:A. ∀b:DeqList A. (tail A (a::b))=b. // qed.
21 lemma list_head: ∀A:DeqSet. ∀a,c:A. ∀b:DeqList A. (hd A (a::b) c)=a. // qed.
22 lemma list_lhdtl: ∀A:DeqSet. ∀a:A. ∀b,l:DeqList A. l=a::b → (a=hd ? l a)∧(b=tail ? l).
23 #A #a #b #l #Hp destruct normalize /2/ qed.
24 lemma list_hdtll: ∀A:DeqSet. ∀a:A. ∀b,l:DeqList A. a::b=l → (a=hd ? l a)∧(b=tail ? l).
25 #A #a #b #l #Hp destruct normalize /2/ qed.
26 (***************************************************************************)
28 (* Definizione di istanza di una tupla *)
29 definition tup_Inst ≝ DeqList DeqCoer.
30 (* Definizione di uno schema di tupla *)
31 definition tup_Sche ≝ DeqList DeqType.
33 (* Dato un'istanza di tupla, riottiene il suo schema *)
34 definition getSchema : tup_Inst → tup_Sche ≝
35 λl. map DeqCoer DeqType getType l.
37 (* PRIMA DEFINIZIONE DI UNA TUPLA:
38 1) Data una lista di schemi ed uno d'istanze, quest'ultimo rispetta i tipi
41 definition tuple ≝ λt. DeqSig tup_Inst (λc. t=(getSchema c)).
42 (* Funzione di creazione di una tupla di primo tipo *)
43 definition mk_tuple : ∀s:tup_Sche. tup_Inst → ? → tuple s ≝
44 λs:tup_Sche.λt:tup_Inst.λp. mk_Sig tup_Inst (λc. s=(getSchema c)) t p.
46 (* Funzioni di equivalenza da getSchema nulla *)
47 lemma gSchema_void: ∀tup. tup= [] → []=getSchema tup.
49 #Coer #ld #IH #Hp >Hp normalize @refl
53 lemma gSchema_hd: ∀a,b. getSchema(a::b)=(getType a)::(getSchema b).
54 #a elim a -a #el #l // qed.
56 lemma gSchema_void2: ∀tup. []=getSchema tup→tup=[].
58 #Coer elim Coer -Coer #C #LD #IH #Hp >gSchema_hd in Hp; #Hp
62 lemma gSchema_hdtl: ∀a,b,c,d. a::b=getSchema(c::d)→a::b=(getType c)::(getSchema d).
63 #a #b #c #d >gSchema_hd #hp @hp qed.
74 (* SECONDA DEFINIZIONE DI UNA TUPLA:
75 2) È un tipo, dove la prima definizione viene inglobata assieme allo schema,
76 ed incorporata in un unico dato
78 record tuple_cast : Type[0] ≝ {
83 (* Lo schema di una tuple_cast è esattamente quello di parametro del suo tipo Σ *)
86 Schema ( (mk_tuple_cast (t::ldt) «dc::ldc,t2») )=t::ldt. // qed.
88 (* Conversione 2 ⇒ 1 *)
89 definition tc_to_t : ∀s:tuple_cast. (tuple (Schema s)).
92 (* Conversione 1 ⇒ 2 *)
93 definition t_to_tc : ∀S. tuple S → tuple_cast ≝ λS,x. mk_tuple_cast S x.
95 (* Lemmi di preservazione della struttura dati: 2 ⇒ 1 ⇒ 2 *)
96 lemma tc_t_tc : ∀x. t_to_tc (Schema x) (tc_to_t x) =x.
97 * #s #t normalize // qed.
98 (* Lemmi di preservazione della struttura dati: 1 ⇒ 2 ⇒ 1 *)
99 lemma t_tc_t: ∀s,t. tc_to_t (t_to_tc s t) = t.
100 #s #t normalize // qed.
102 lemma base_coerc1: ∀x. (getType (CNat x))=Nat. // qed.
103 lemma base_coerc2: ∀x. (getType (CBool x))=Bool. // qed.
105 (* Definizione di una tupla con un singolo elemento: questa può essere effettuata
106 fornendo unicamente il valore del dato (1)
108 definition singleton: ∀c:DeqCoer. tuple [getType c].
110 [ >base_coerc1 @(mk_tuple [Nat] [CNat V] (refl ? [Nat]))
111 | >base_coerc2 @(mk_tuple [Bool] [CBool V] (refl ? [Bool]))]. qed.
113 (* Definizione di tuple vuote rispettivamente di tipo 1 e 2 *)
114 definition voideton: tuple []. @(mk_tuple [] [] (refl ? [])) qed.
115 definition voideton2 ≝ mk_tuple_cast [] voideton.
117 lemma voideton_eq: ∀t:tuple[]. mk_tuple_cast [] t = voideton2.
119 [ #prop normalize @eq_f destruct //
120 | #dc #ldc #IH #AI lapply (gSchema_void2 … AI) #AI2 destruct
124 (******************************************************************************)
131 (**************************************************)
132 (* Definizione della funzione di proiezione per 1 *)
133 (**************************************************)
134 (* Funzione per la restituzione del tipo di dato opportuno dato un valore opzionale *)
135 definition optScheme : option DeqCoer→tup_Sche ≝ λu.
138 | Some a ⇒ [getType a]].
140 (* Funzione per l'istanziazione della tupla dal risultato della coercizione *)
141 definition proj_5t: ∀x:option DeqCoer. tuple (optScheme x).
143 | #arg @(singleton arg)] qed.
145 (* Funzione di proiezione per 1 *)
146 definition proj_t1: ∀s:tup_Sche.∀t:tuple s. ℕ→tuple ?.
147 [ #s #t #i @(proj_5t (nth_opt ? i (Sig_fst ? ? t) )) ] skip qed.
149 (* Definizione della proiezione in posizione (S n)-esima *)
152 optScheme (nth_opt DeqCoer (S n) (dc::ld))=optScheme (nth_opt DeqCoer n ld).
154 #n #dc #ld normalize // qed.
160 (**************************************************)
161 (* Definizione della funzione di proiezione per 2 *)
162 (**************************************************)
163 definition proj_t2 ≝ λtc,i.
164 match nth_opt ? i (Sig_fst ? ? (Tuple tc)) with
165 [ None ⇒ mk_tuple_cast [] voideton
166 | Some a ⇒ mk_tuple_cast [getType a] (singleton a)].
168 (* Lemmi sulla funzione di proiezione *)
169 lemma proj_t2_null: ∀i. proj_t2 voideton2 i = voideton2.
171 lemma proj_t2_head: ∀a. proj_t2 (mk_tuple_cast [getType a] (singleton a)) O = mk_tuple_cast [getType a] (singleton a).
173 lemma proj_t2_head_N: ∀a,i. proj_t2 (mk_tuple_cast [getType a] (singleton a)) (S i)=voideton2.
177 (******************************************************************************)
179 (* Definizione di proiezione dell'elemento (S x)-esimo elemento per ogni tipo di
181 theorem proj_t1_tl: ∀dt,ldt,ld,IH,prop,pos.
183 (proj_t1 (dt::ldt) «ld::IH,prop» (S pos)) = (proj_t1 (ldt) «IH,?» (pos)).
185 [ #d #ld #dc #ldl #prop #pos //
186 | lapply (list_hdtll … prop) * >list_tail >list_head
187 #h @(rewrite_r … (getSchema IH)) //
192 (* Rappresentazione di una lista di "tipi" dalla rappresentazione del valore *)
193 lemma proj_t2_tl_deq_Type:
194 ∀dt:DeqType. ∀ldt:list DeqType. ∀ld:DeqCoer.
195 ∀IH:list DeqCoer.∀prop: dt::ldt=getSchema (ld::IH).
199 #d #ld #dc #ldl #prop
200 lapply (list_hdtll … prop) * >list_tail >list_head
201 #h @(rewrite_r … (getSchema ldl)) // qed.
205 (* Definizione della proiezione sul secondo tipo di tupla *)
206 theorem proj_t2_tl : ∀dt,ldt,ld,IH,prop,pos.
208 proj_t2 (t_to_tc (dt::ldt) «ld::IH,prop») (S pos)
209 = proj_t2 (t_to_tc ldt «IH,?») pos.
211 [ #d #ld #dc #ldl #prop #pos //
212 | @(proj_t2_tl_deq_Type dt ldt ld IH prop)
217 (******************************************************************************)
219 (* Una tupla vuota per 1) è un voideton 2) *)
220 lemma t_to_tc_void_as_voideton2 : ∀t: tuple []. t_to_tc [] t = voideton2.
223 normalize lapply (gSchema_void2 … prop) #Hp
230 (* Una qualunque proiezione di un tipo di tupla 1) restituirà nessun elemento *)
231 lemma voidopt_lemma: ∀t,pos.
232 (nth_opt DeqCoer pos (Sig_fst tup_Inst (λc:tup_Inst.[]=getSchema c) t))
234 #t elim t -t #is #prop #n lapply (gSchema_void2 … prop) #Hp destruct
239 lemma void_optS: (optScheme (None DeqCoer)) = []. // qed.
240 lemma void_tup: (tuple (optScheme (None DeqCoer)))= tuple []. >void_optS // qed.
244 (* Valutazione di una proiezione di tupla vuota 1) come eq_rect_Type0_r *)
245 lemma proj_nothing_void : ∀t:tuple []. ∀pos. (proj_t1 [] t pos)= ?.
246 [ 2: >voidopt_lemma >void_tup @t
247 | #t elim t -t #s #prop lapply (gSchema_void2 … prop) #Hp #pos
248 destruct normalize // qed.
249 (* check proj_nothing_void *)
250 lemma proj_nothing_voideton: ∀pos. proj_t2 voideton2 pos = voideton2.
251 #n elim n -n normalize // qed.
253 (* Valutazione di una proiezione di una tupla vuota 2) come voideton2
254 lemma t_to_c_proj1_void:
255 ∀dt, ldt, s1,n. proj_t2 (t_to_tc (dt::ldt) «[],s1») n = voideton2. // qed.
261 (* Se la restituzione di uno schema per una istanza l è a::b, allora
262 b sarà pari allo schema ottenibile dal resto di l *)
263 lemma gSchema_tl: ∀a,b,l. a::b=getSchema l → b = getSchema (tail DeqCoer l).
267 [ #Hp normalize in Hp; normalize destruct
268 | #dc #ldc #IH #Hp >list_tail lapply (list_lhdtl …Hp) *
269 >list_head #oH1 >list_tail @(rewrite_l … (getSchema ldc)) //]
270 | #ldt #el1 -el1 #l elim l -l
272 | #DC #ldc #IH #hp >list_tail lapply (list_hdtll … hp) -hp
273 >list_head >list_tail * #oh1 @(rewrite_r … (getSchema ldc)) //
275 | #ldt #m #d -d -ldt #u #IH #l elim l
276 [ #Hp lapply (IH … []) normalize #banal normalize in Hp; destruct
277 | #dc #ldc #IH #e1 >list_tail lapply (list_hdtll … e1) >list_head
278 * #oh1 >list_tail @(rewrite_r … (getSchema ldc)) //
285 lemma gSchema_tltl: ∀b,l. b=getSchema l → tail DeqType b = getSchema (tail DeqCoer l).
287 [ #l #prop lapply(gSchema_void2 … prop) #lP >lP normalize //
288 | #dT #ldT #IH #tI #Hp whd in ⊢ (?? % ?); lapply (gSchema_tl … Hp) -Hp
295 lemma gSchema_rest: ∀a,b,e,l. a::b=getSchema (e::l) → b = getSchema (l).
296 #a #b #e #l @gSchema_tl qed.
298 (* "Coercizione" per eq_rect_Type0_r *)
302 (nth_opt DeqCoer pos (Sig_fst tup_Inst (λc:tup_Inst.[]=getSchema c) t)))
307 #t #pos>proj_nothing_void >voidopt_lemma normalize // qed.
312 (******************************************************************************)
314 (* Equivalenza tra schemi nell'elemento (S pos)-esimo *)
315 lemma nthopt_S: ∀pos,t,ldt,dc,ldc,t2.
317 (nth_opt DeqCoer (S pos)
318 (Sig_fst tup_Inst (λc:tup_Inst.t::ldt=getSchema c)
319 (tc_to_t (mk_tuple_cast (t::ldt) «dc::ldc,t2»)))) =
320 (nth_opt DeqCoer ( pos)
321 (Sig_fst tup_Inst (λc:tup_Inst.ldt=getSchema c)
322 (tc_to_t (mk_tuple_cast (ldt) «ldc,?»)))).
324 [ #p #dt #ldt #dc #ldc #hp normalize //
325 | lapply (gSchema_tl … t2) #t3 normalize in t3;
330 (* Specializzazione del caso precedente, tramite estrazione diretta della
331 componente dello schema *)
332 lemma nthopt_S2: ∀pos,t,ldt,dc,ldc,t2.
334 (nth_opt DeqCoer (S pos)
335 (Sig_fst tup_Inst (λc:tup_Inst.t::ldt=getSchema c)
336 (tc_to_t (mk_tuple_cast (t::ldt) «dc::ldc,t2»))))=
337 (nth_opt DeqCoer pos ldc).
339 #pos #dt #ldt #dc #ldc #p >nthopt_S normalize // qed.
341 (******************************************************************************)
347 (* Qualsiasi proiezione di uno schema vuoto è esso stesso uno schema vuoto *)
348 lemma coerc2: ∀t:tuple [].∀pos. (Schema (proj_t2 (mk_tuple_cast [] t) pos))=[].
350 * #ti #prop #p >voideton_eq normalize @refl qed.
354 lemma coerc3 : ∀t,ldt,ins,prop.
356 (Sig_fst tup_Inst (λc:tup_Inst.t::ldt=getSchema c)
357 (tc_to_t (mk_tuple_cast (t::ldt) «ins,prop»)))=ins.
359 #dt #ldt #ti #p normalize @refl qed.
364 (* Le due definizioni di proiezione di tupla preservano la proiezione per il
365 tipo 1) lungo le funzioni di conversione per 2) *)
366 theorem preservation1:
367 ∀s,t,i. proj_t2 (t_to_tc s t) i = (t_to_tc ? (proj_t1 s t i)).
369 [ #t #pos >t_to_tc_void_as_voideton2
370 >proj_nothing_voideton
374 lapply (gSchema_void2 … prop)
379 [ #prop #pos normalize //
380 | #ld #IH #Hp #prop #pos elim pos -pos
382 | #pos #Hp2 >proj_t1_tl >proj_t2_tl //
391 (* Equivalenza tra schemi di tuple cast *)
392 lemma eqSchema: ∀a,b:tuple_cast. a=b → (Schema a)=(Schema b).
393 * #ts1 #t1 * #ts2 #t2 #Hp destruct @refl qed.
398 (* Data una tuple_schema a ed uno schema b, se i due schemi sono uguali,
399 allora posso restituire una tupla di schema b *)
400 lemma tTupleSchema: ∀a,b. (Schema a)=b → tuple b.
401 * #schema #inst #bschema #ref <ref @inst qed.
405 (* Data una tupla a di schema s ed uno schema b, se s=b allora restituisco
406 la tupla come di schema b *)
407 lemma tTuple: ∀s,b. ∀a:tuple s. s=b → tuple b.
408 #a #b #inp #ref <ref @inp qed.
412 (* Identità di t tra funzioni *)
413 lemma tctt_void_preservation: ∀t:tuple []. (tc_to_t (mk_tuple_cast [] t)) = t.
414 * #p #pr normalize @refl qed.