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 (* ********************************************************************** *)
18 (* Cosimo Oliboni, oliboni@cs.unibo.it *)
20 (* ********************************************************************** *)
22 include "compiler/environment.ma".
24 (* ********************** *)
25 (* GESTIONE AMBIENTE FLAT *)
26 (* ********************** *)
29 inductive var_flatElem : Type ≝
30 VAR_FLAT_ELEM: aux_strId_type → desc_elem → var_flatElem.
32 definition get_name_flatVar ≝ λv:var_flatElem.match v with [ VAR_FLAT_ELEM n _ ⇒ n ].
33 definition get_desc_flatVar ≝ λv:var_flatElem.match v with [ VAR_FLAT_ELEM _ d ⇒ d ].
35 definition aux_flatEnv_type ≝ list var_flatElem.
37 definition empty_flatEnv ≝ nil var_flatElem.
39 (* mappa: nome + max + cur *)
40 inductive n_list : nat → Type ≝
42 | n_cons: ∀n.option nat → n_list n → n_list (S n).
44 definition defined_nList ≝
45 λd.λl:n_list d.match l with [ n_nil ⇒ False | n_cons _ _ _ ⇒ True ].
47 definition cut_first_nList : Πd.n_list d → ? → n_list (pred d) ≝
48 λd.λl:n_list d.λp:defined_nList ? l.
51 return λX.λY:n_list X.defined_nList X Y → n_list (pred X)
53 [ n_nil ⇒ λp:defined_nList O n_nil.False_rect ? p
54 | n_cons n h t ⇒ λp:defined_nList (S n) (n_cons n h t).t
57 definition get_first_nList : Πd.n_list d → ? → option nat ≝
58 λd.λl:n_list d.λp:defined_nList ? l.
61 return λX.λY:n_list X.defined_nList X Y → option nat
63 [ n_nil ⇒ λp:defined_nList O n_nil.False_rect ? p
64 | n_cons n h t ⇒ λp:defined_nList (S n) (n_cons n h t).h
67 inductive map_elem (d:nat) : Type ≝
68 MAP_ELEM: aux_str_type → nat → n_list (S d) → map_elem d.
70 definition get_name_mapElem ≝ λd.λm:map_elem d.match m with [ MAP_ELEM n _ _ ⇒ n ].
71 definition get_max_mapElem ≝ λd.λm:map_elem d.match m with [ MAP_ELEM _ m _ ⇒ m ].
72 definition get_cur_mapElem ≝ λd.λm:map_elem d.match m with [ MAP_ELEM _ _ c ⇒ c ].
74 definition aux_map_type ≝ λd.list (map_elem d).
76 definition empty_map ≝ nil (map_elem O).
78 axiom defined_nList_S_to_true :
79 ∀d.∀l:n_list (S d).defined_nList (S d) l = True.
81 lemma defined_get_id :
82 ∀d.∀h:map_elem d.True → defined_nList (S d) (get_cur_mapElem d h).
84 rewrite > (defined_nList_S_to_true ? (get_cur_mapElem d h));
89 let rec get_id_map_aux d (map:aux_map_type d) (name:aux_str_type) on map : option nat ≝
92 | cons h t ⇒ match eqStr_str name (get_name_mapElem d h) with
93 [ true ⇒ get_first_nList (S d) (get_cur_mapElem d h) (defined_get_id ?? I)
94 | false ⇒ get_id_map_aux d t name
98 definition get_id_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
99 match get_id_map_aux d map name with [ None ⇒ O | Some x ⇒ x ].
102 let rec get_max_map_aux d (map:aux_map_type d) (name:aux_str_type) on map ≝
105 | cons h t ⇒ match eqStr_str name (get_name_mapElem d h) with
106 [ true ⇒ Some ? (get_max_mapElem d h)
107 | false ⇒ get_max_map_aux d t name
111 definition get_max_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
112 match get_max_map_aux d map name with [ None ⇒ O | Some x ⇒ x ].
115 definition check_id_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
116 match get_id_map_aux d map name with [ None ⇒ False | Some _ ⇒ True ].
118 definition checkb_id_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
119 match get_id_map_aux d map name with [ None ⇒ false | Some _ ⇒ true ].
121 lemma checkbidmap_to_checkidmap : ∀d.∀map:aux_map_type d.∀name.checkb_id_map d map name = true → check_id_map d map name.
122 unfold checkb_id_map;
125 elim (get_id_map_aux d map name) 0;
126 [ simplify; intro; destruct H
127 | simplify; intros; apply I
131 definition checknot_id_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
132 match get_id_map_aux d map name with [ None ⇒ True | Some _ ⇒ False ].
134 definition checknotb_id_map ≝ λd.λmap:aux_map_type d.λname:aux_str_type.
135 match get_id_map_aux d map name with [ None ⇒ true | Some _ ⇒ false ].
137 lemma checknotbidmap_to_checknotidmap : ∀d.∀map:aux_map_type d.∀name.checknotb_id_map d map name = true → checknot_id_map d map name.
138 unfold checknotb_id_map;
139 unfold checknot_id_map;
141 elim (get_id_map_aux d map name) 0;
142 [ simplify; intro; apply I
143 | simplify; intros; destruct H
148 let rec get_desc_flatEnv_aux (fe:aux_flatEnv_type) (name:aux_strId_type) on fe ≝
151 | cons h t ⇒ match eqStrId_str name (get_name_flatVar h) with
152 [ true ⇒ Some ? (get_desc_flatVar h)
153 | false ⇒ get_desc_flatEnv_aux t name
157 definition get_desc_flatEnv ≝ λfe:aux_flatEnv_type.λstr:aux_strId_type.
158 match get_desc_flatEnv_aux fe str with
159 [ None ⇒ DESC_ELEM true (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) | Some x ⇒ x ].
161 definition check_desc_flatEnv ≝ λfe:aux_flatEnv_type.λstr:aux_strId_type.
162 match get_desc_flatEnv_aux fe str with [ None ⇒ False | Some _ ⇒ True ].
164 definition checkb_desc_flatEnv ≝ λfe:aux_flatEnv_type.λstr:aux_strId_type.
165 match get_desc_flatEnv_aux fe str with [ None ⇒ false | Some _ ⇒ true ].
167 lemma checkbdescflatenv_to_checkdescflatenv : ∀fe,str.checkb_desc_flatEnv fe str = true → check_desc_flatEnv fe str.
168 unfold checkb_desc_flatEnv;
169 unfold check_desc_flatEnv;
171 elim (get_desc_flatEnv_aux fe str) 0;
172 [ simplify; intro; destruct H
173 | simplify; intros; apply I
177 definition checknot_desc_flatEnv ≝ λfe:aux_flatEnv_type.λstr:aux_strId_type.
178 match get_desc_flatEnv_aux fe str with [ None ⇒ True | Some _ ⇒ False ].
180 definition checknotb_desc_flatEnv ≝ λfe:aux_flatEnv_type.λstr:aux_strId_type.
181 match get_desc_flatEnv_aux fe str with [ None ⇒ true | Some _ ⇒ false ].
183 lemma checknotbdescflatenv_to_checknotdescflatenv : ∀fe,str.checknotb_desc_flatEnv fe str = true → checknot_desc_flatEnv fe str.
184 unfold checknotb_desc_flatEnv;
185 unfold checknot_desc_flatEnv;
187 elim (get_desc_flatEnv_aux fe str) 0;
188 [ simplify; intro; apply I
189 | simplify; intros; destruct H
194 definition eq_flatEnv_elem ≝
196 [ VAR_FLAT_ELEM sId1 d1 ⇒ match e2 with
197 [ VAR_FLAT_ELEM sId2 d2 ⇒ (eqStrId_str sId1 sId2)⊗(eqDesc_elem d1 d2) ]].
199 lemma eq_to_eqflatenv : ∀e1,e2.e1 = e2 → eq_flatEnv_elem e1 e2 = true.
204 rewrite > (eq_to_eqstrid a a (refl_eq ??));
205 rewrite > (eq_to_eqdescelem d d (refl_eq ??));
209 lemma eqflatenv_to_eq : ∀e1,e2.eq_flatEnv_elem e1 e2 = true → e1 = e2.
216 rewrite > (eqstrid_to_eq a1 a (andb_true_true ?? H));
217 rewrite > (eqdescelem_to_eq d1 d (andb_true_true_r ?? H));
221 let rec le_flatEnv (fe,fe':aux_flatEnv_type) on fe ≝
224 | cons h tl ⇒ match fe' with
225 [ nil ⇒ false | cons h' tl' ⇒ (eq_flatEnv_elem h h')⊗(le_flatEnv tl tl') ]
228 lemma eq_to_leflatenv : ∀e1,e2.e1 = e2 → le_flatEnv e1 e2 = true.
234 rewrite > (eq_to_eqflatenv a a (refl_eq ??));
240 lemma leflatEnv_to_le : ∀fe,fe'.le_flatEnv fe fe' = true → ∃x.fe@x=fe'.
243 [ intros; exists; [ apply fe' | reflexivity ]
244 | intros 4; elim fe';
245 [ simplify in H1:(%); destruct H1
246 | simplify in H2:(%);
247 rewrite < (eqflatenv_to_eq a a1 (andb_true_true ?? H2));
248 cases (H l1 (andb_true_true_r ?? H2));
251 exists; [ apply x | reflexivity ]
256 lemma le_to_leflatenv : ∀fe,x.le_flatEnv fe (fe@x) = true.
262 rewrite > (eq_to_eqflatenv a a (refl_eq ??));
268 lemma leflatenv_to_check : ∀fe,fe',str.
269 (le_flatEnv fe fe' = true) →
270 (check_desc_flatEnv fe str) →
271 (check_desc_flatEnv fe' str).
273 cases (leflatEnv_to_le fe fe' H);
276 [ intro; simplify in H2:(%); elim H2;
279 cases (eqStrId_str str (get_name_flatVar a));
280 [ simplify; intro; apply H3
286 lemma leflatenv_to_get : ∀fe,fe',str.
287 (le_flatEnv fe fe' = true) →
288 (check_desc_flatEnv fe str) →
289 (get_desc_flatEnv fe str = get_desc_flatEnv fe' str).
291 cases (leflatEnv_to_le fe fe' H);
299 cases (eqStrId_str str (get_name_flatVar a));
304 unfold check_desc_flatEnv;
305 unfold get_desc_flatEnv;
306 cases (get_desc_flatEnv_aux l str);
307 [ simplify; intros; elim H3
308 | simplify; intros; rewrite < (H2 H3); reflexivity
315 definition env_to_flatEnv_inv ≝
316 λd.λe:aux_env_type.λmap:aux_map_type d.λfe:aux_flatEnv_type.
318 check_desc_env e str →
319 (check_id_map d map str ∧
320 check_desc_flatEnv fe (STR_ID str (get_id_map d map str)) ∧
321 get_desc_env e str = get_desc_flatEnv fe (STR_ID str (get_id_map d map str))).
323 lemma inv_to_checkdescflatenv :
324 ∀d.∀e.∀map:aux_map_type d.∀fe.
325 env_to_flatEnv_inv d e map fe →
326 (∀str.check_desc_env e str → check_desc_flatEnv fe (STR_ID str (get_id_map d map str))).
328 unfold env_to_flatEnv_inv in H:(%);
330 apply (proj2 ?? (proj1 ?? Hletin));
333 lemma env_map_flatEnv_empty_aux : env_to_flatEnv_inv O empty_env empty_map empty_flatEnv.
334 unfold env_to_flatEnv_inv;
337 unfold empty_flatEnv;
341 [ split; apply H | reflexivity ].
344 lemma leflatenv_to_inv :
345 ∀d.∀e.∀map:aux_map_type d.∀fe,fe'.
346 le_flatEnv fe fe' = true →
347 env_to_flatEnv_inv d e map fe →
348 env_to_flatEnv_inv d e map fe'.
350 unfold env_to_flatEnv_inv;
354 [ lapply (H1 str H2);
355 apply (proj1 ?? (proj1 ?? Hletin))
356 | lapply (H1 str H2);
357 apply (leflatenv_to_check fe fe' ? H (proj2 ?? (proj1 ?? Hletin)))
359 | lapply (H1 str H2);
360 rewrite < (leflatenv_to_get fe fe' ? H (proj2 ?? (proj1 ?? Hletin)));
361 apply (proj2 ?? Hletin)
365 (* enter: propaga in testa la vecchia testa (il "cur" precedente) *)
366 let rec enter_map d (map:aux_map_type d) on map ≝
371 (get_name_mapElem d h)
372 (get_max_mapElem d h)
374 (get_first_nList ? (get_cur_mapElem d h) (defined_get_id ?? I))
375 (get_cur_mapElem d h))
379 lemma getidmap_to_enter :
380 ∀d.∀m:aux_map_type d.∀str.
381 get_id_map_aux (S d) (enter_map d m) str = get_id_map_aux d m str.
384 [ simplify; reflexivity
385 | simplify; rewrite > H; reflexivity
389 lemma env_map_flatEnv_enter_aux :
390 ∀d.∀e.∀map:aux_map_type d.∀fe.
391 env_to_flatEnv_inv d e map fe → env_to_flatEnv_inv (S d) (enter_env e) (enter_map d map) fe.
395 unfold env_to_flatEnv_inv;
399 [ simplify; intros; split;
400 [ apply (proj1 ?? (H str H1)) | apply (proj2 ?? (H str H1)); ]
401 | simplify; intros; split;
402 [ rewrite > (getidmap_to_enter d l str); apply (proj1 ?? (H1 str H2))
403 | rewrite > (getidmap_to_enter d l str); apply (proj2 ?? (H1 str H2))
407 [ simplify; intros; split;
408 [ apply (proj1 ?? (H1 str H2)) | apply (proj2 ?? (H1 str H2)) ]
409 | simplify; intros; split;
410 [ rewrite > (getidmap_to_enter d l str); apply (proj1 ?? (H2 str H3))
411 | rewrite > (getidmap_to_enter d l str); apply (proj2 ?? (H2 str H3))
417 (* leave: elimina la testa (il "cur" corrente) *)
418 let rec leave_map d (map:aux_map_type (S d)) on map ≝
423 (get_name_mapElem (S d) h)
424 (get_max_mapElem (S d) h)
425 (cut_first_nList ? (get_cur_mapElem (S d) h) (defined_get_id ?? I))
429 (* aggiungi descrittore *)
430 let rec new_map_elem_from_depth_aux (d:nat) on d ≝
435 | S n ⇒ n_cons n (None ?) (new_map_elem_from_depth_aux n)
438 let rec new_max_map_aux d (map:aux_map_type d) (name:aux_str_type) (max:nat) on map ≝
441 | cons h t ⇒ match eqStr_str name (get_name_mapElem d h) with
442 [ true ⇒ MAP_ELEM d name max (n_cons d (Some ? max) (cut_first_nList (S d) (get_cur_mapElem d h) (defined_get_id ?? I)))
444 ]::(new_max_map_aux d t name max)
447 definition add_desc_env_flatEnv_map ≝
448 λd.λmap:aux_map_type d.λstr.
449 match get_max_map_aux d map str with
450 [ None ⇒ map@[ MAP_ELEM d str O (n_cons d (Some ? O) (new_map_elem_from_depth_aux d)) ]
451 | Some x ⇒ new_max_map_aux d map str (S x)
454 definition add_desc_env_flatEnv_fe ≝
455 λd.λmap:aux_map_type d.λfe.λstr.λc.λdesc.
456 fe@[ VAR_FLAT_ELEM (STR_ID str match get_max_map_aux d map str with [ None ⇒ O | Some x ⇒ (S x)])
457 (DESC_ELEM c desc) ].
459 let rec build_trasfEnv_env (trsf:list (Prod3T aux_str_type bool ast_type)) e on trsf ≝
462 | cons h t ⇒ build_trasfEnv_env t (add_desc_env e (fst3T ??? h) (snd3T ??? h) (thd3T ??? h))
465 let rec build_trasfEnv_mapFe (trasf:list ?) d (mfe:Prod (aux_map_type d) aux_flatEnv_type) on trasf ≝
469 build_trasfEnv_mapFe t d (pair ?? (add_desc_env_flatEnv_map d (fst ?? mfe) (fst3T ??? h))
470 (add_desc_env_flatEnv_fe d (fst ?? mfe) (snd ?? mfe) (fst3T ??? h) (snd3T ??? h) (thd3T ??? h)))
473 (* avanzamento delle dimostrazioni *)
474 axiom env_map_flatEnv_add_aux :
475 ∀d.∀e.∀map:aux_map_type d.∀fe.∀trsf.
476 env_to_flatEnv_inv d e map fe →
478 (build_trasfEnv_env trsf e)
479 (fst ?? (build_trasfEnv_mapFe trsf d (pair ?? map fe)))
480 (snd ?? (build_trasfEnv_mapFe trsf d (pair ?? map fe))).
482 axiom env_map_flatEnv_add_aux_fe :
483 ∀d.∀map:aux_map_type d.∀fe,trsf.
484 ∃x.fe@x = (snd ?? (build_trasfEnv_mapFe trsf d (pair ?? map fe))).
486 lemma buildtrasfenvadd_to_le :
487 ∀d.∀m:aux_map_type d.∀fe,trsf.
488 le_flatEnv fe (snd ?? (build_trasfEnv_mapFe trsf d (pair ?? m fe))) = true.
490 cases (env_map_flatEnv_add_aux_fe d m fe trsf);
492 rewrite > (le_to_leflatenv fe x);
496 axiom env_map_flatEnv_leave_aux :
497 ∀d.∀e.∀map:aux_map_type (S d).∀fe.
498 env_to_flatEnv_inv (S d) e map fe →
504 (* avanzamento congiunto oggetti + dimostrazioni *)
505 inductive env_map_flatEnv :
506 Πd.Πe.Πm:aux_map_type d.Πfe,fe'.
507 env_to_flatEnv_inv d e m fe' →
508 le_flatEnv fe fe' = true → Type ≝
509 ENV_MAP_FLATENV_EMPTY: env_map_flatEnv O
514 env_map_flatEnv_empty_aux
515 (eq_to_leflatenv ?? (refl_eq ??))
516 | ENV_MAP_FLATENV_ENTER: ∀d,e.∀m:aux_map_type d.∀fe,fe'.
517 ∀dimInv:env_to_flatEnv_inv d e m fe'.
518 ∀dimLe:le_flatEnv fe fe' = true.
519 env_map_flatEnv d e m fe fe' dimInv dimLe →
520 env_map_flatEnv (S d)
525 (env_map_flatEnv_enter_aux d e m fe' dimInv)
526 (eq_to_leflatenv ?? (refl_eq ??))
527 | ENV_MAP_FLATENV_ADD: ∀d,e.∀m:aux_map_type d.∀fe,fe'.
528 ∀dimInv:env_to_flatEnv_inv d e m fe'.
529 ∀dimLe:le_flatEnv fe fe' = true.∀trsf.
530 env_map_flatEnv d e m fe fe' dimInv dimLe →
532 (build_trasfEnv_env trsf e)
533 (fst ?? (build_trasfEnv_mapFe trsf d (pair ?? m fe')))
535 (snd ?? (build_trasfEnv_mapFe trsf d (pair ?? m fe')))
536 (env_map_flatEnv_add_aux d e m fe' trsf dimInv)
537 (buildtrasfenvadd_to_le d m fe' trsf)
538 | ENV_MAP_FLATENV_LEAVE: ∀d,e.∀m:aux_map_type (S d).∀fe,fe'.
539 ∀dimInv:env_to_flatEnv_inv (S d) e m fe'.
540 ∀dimLe:le_flatEnv fe fe' = true.
541 env_map_flatEnv (S d) e m fe fe' dimInv dimLe →
547 (env_map_flatEnv_leave_aux d e m fe' dimInv)
548 (eq_to_leflatenv ?? (refl_eq ??)).