--- /dev/null
+(**************************************************************************)
+(* ___ *)
+(* ||M|| *)
+(* ||A|| A project by Andrea Asperti *)
+(* ||T|| *)
+(* ||I|| Developers: *)
+(* ||T|| The HELM team. *)
+(* ||A|| http://helm.cs.unibo.it *)
+(* \ / *)
+(* \ / This file is distributed under the terms of the *)
+(* v GNU General Public License Version 2 *)
+(* *)
+(**************************************************************************)
+
+(* ********************************************************************** *)
+(* Progetto FreeScale *)
+(* *)
+(* Sviluppato da: Cosimo Oliboni, oliboni@cs.unibo.it *)
+(* Cosimo Oliboni, oliboni@cs.unibo.it *)
+(* *)
+(* ********************************************************************** *)
+
+include "common/list_utility.ma".
+
+(* ************************* *)
+(* dimensioni degli elementi *)
+(* ************************* *)
+
+(* usato per definire nell'ast *)
+ninductive ast_base_type : Type ≝
+ AST_BASE_TYPE_BYTE8: ast_base_type
+| AST_BASE_TYPE_WORD16: ast_base_type
+| AST_BASE_TYPE_WORD32: ast_base_type.
+
+ninductive ast_type : Type ≝
+ AST_TYPE_BASE: ast_base_type → ast_type
+| AST_TYPE_ARRAY: ast_type → nat → ast_type
+| AST_TYPE_STRUCT: ne_list ast_type → ast_type.
+
+(* principio di eliminazione arricchito *)
+nlet rec ast_type_index_aux (P:ast_type → Prop)
+ (f:Πt.P t → P (AST_TYPE_STRUCT (ne_nil ? t)))
+ (f1:Πh,t.P h → P (AST_TYPE_STRUCT t) → P (AST_TYPE_STRUCT (ne_cons ? h t)))
+ (f2:Πt.P t)
+ (t:ne_list ast_type) on t ≝
+ match t return λt.P (AST_TYPE_STRUCT t) with
+ [ ne_nil h ⇒ f h (f2 h)
+ | ne_cons h t ⇒ f1 h t (f2 h) (ast_type_index_aux P f f1 f2 t)
+ ].
+
+nlet rec ast_type_index (P:ast_type → Prop)
+ (f:Πb.P (AST_TYPE_BASE b))
+ (f1:Πt,n.P t → P (AST_TYPE_ARRAY t n))
+ (f2:Πt.P t → P (AST_TYPE_STRUCT (ne_nil ? t)))
+ (f3:Πh,t.P h → P (AST_TYPE_STRUCT t) → P (AST_TYPE_STRUCT (ne_cons ? h t)))
+ (t:ast_type) on t : P t ≝
+ match t return λt.P t with
+ [ AST_TYPE_BASE b ⇒ f b
+ | AST_TYPE_ARRAY t' n ⇒ f1 t' n (ast_type_index P f f1 f2 f3 t')
+ | AST_TYPE_STRUCT nl ⇒ match nl with
+ [ ne_nil h ⇒ f2 h (ast_type_index P f f1 f2 f3 h)
+ | ne_cons h t ⇒ f3 h t (ast_type_index P f f1 f2 f3 h) (ast_type_index_aux P f2 f3 (ast_type_index P f f1 f2 f3) t)
+ ]
+ ].
+
+nlet rec ast_type_rectex_aux (P:ast_type → Type)
+ (f:Πt.P t → P (AST_TYPE_STRUCT (ne_nil ? t)))
+ (f1:Πh,t.P h → P (AST_TYPE_STRUCT t) → P (AST_TYPE_STRUCT (ne_cons ? h t)))
+ (f2:Πt.P t)
+ (t:ne_list ast_type) on t ≝
+ match t return λt.P (AST_TYPE_STRUCT t) with
+ [ ne_nil h ⇒ f h (f2 h)
+ | ne_cons h t ⇒ f1 h t (f2 h) (ast_type_rectex_aux P f f1 f2 t)
+ ].
+
+nlet rec ast_type_rectex (P:ast_type → Type)
+ (f:Πb.P (AST_TYPE_BASE b))
+ (f1:Πt,n.P t → P (AST_TYPE_ARRAY t n))
+ (f2:Πt.P t → P (AST_TYPE_STRUCT (ne_nil ? t)))
+ (f3:Πh,t.P h → P (AST_TYPE_STRUCT t) → P (AST_TYPE_STRUCT (ne_cons ? h t)))
+ (t:ast_type) on t : P t ≝
+ match t return λt.P t with
+ [ AST_TYPE_BASE b ⇒ f b
+ | AST_TYPE_ARRAY t' n ⇒ f1 t' n (ast_type_rectex P f f1 f2 f3 t')
+ | AST_TYPE_STRUCT nl ⇒ match nl with
+ [ ne_nil h ⇒ f2 h (ast_type_rectex P f f1 f2 f3 h)
+ | ne_cons h t ⇒ f3 h t (ast_type_rectex P f f1 f2 f3 h) (ast_type_rectex_aux P f2 f3 (ast_type_rectex P f f1 f2 f3) t)
+ ]
+ ].
+
+ndefinition eq_ast_base_type ≝
+λt1,t2:ast_base_type.match t1 with
+ [ AST_BASE_TYPE_BYTE8 ⇒ match t2 with
+ [ AST_BASE_TYPE_BYTE8 ⇒ true | _ ⇒ false ]
+ | AST_BASE_TYPE_WORD16 ⇒ match t2 with
+ [ AST_BASE_TYPE_WORD16 ⇒ true | _ ⇒ false ]
+ | AST_BASE_TYPE_WORD32 ⇒ match t2 with
+ [ AST_BASE_TYPE_WORD32 ⇒ true | _ ⇒ false ]
+ ].
+
+nlet rec eq_ast_type (t1,t2:ast_type) on t1 ≝
+ match t1 with
+ [ AST_TYPE_BASE bType1 ⇒ match t2 with
+ [ AST_TYPE_BASE bType2 ⇒ eq_ast_base_type bType1 bType2
+ | _ ⇒ false ]
+ | AST_TYPE_ARRAY subType1 dim1 ⇒ match t2 with
+ [ AST_TYPE_ARRAY subType2 dim2 ⇒ (eq_ast_type subType1 subType2) ⊗ (eq_nat dim1 dim2)
+ | _ ⇒ false ]
+ | AST_TYPE_STRUCT nelSubType1 ⇒ match t2 with
+ [ AST_TYPE_STRUCT nelSubType2 ⇒ bfold_right_neList2 ? (λx1,x2.eq_ast_type x1 x2) nelSubType1 nelSubType2
+ | _ ⇒ false
+ ]
+ ].
+
+ndefinition is_ast_base_type ≝
+λast:ast_type.match ast with [ AST_TYPE_BASE _ ⇒ True | _ ⇒ False ].
+
+ndefinition isb_ast_base_type ≝
+λast:ast_type.match ast with [ AST_TYPE_BASE _ ⇒ true | _ ⇒ false ].
+
+ndefinition isnt_ast_base_type ≝
+λast:ast_type.match ast with [ AST_TYPE_BASE _ ⇒ False | _ ⇒ True ].
+
+ndefinition isntb_ast_base_type ≝
+λast:ast_type.match ast with [ AST_TYPE_BASE _ ⇒ false | _ ⇒ true ].
+
+ndefinition eval_size_base_type ≝
+λast:ast_base_type.match ast with
+ [ AST_BASE_TYPE_BYTE8 ⇒ 1
+ | AST_BASE_TYPE_WORD16 ⇒ 2
+ | AST_BASE_TYPE_WORD32 ⇒ 4
+ ].
+
+nlet rec eval_size_type (ast:ast_type) on ast ≝
+ match ast with
+ [ AST_TYPE_BASE b ⇒ eval_size_base_type b
+ | AST_TYPE_ARRAY sub_ast dim ⇒ (dim+1)*(eval_size_type sub_ast)
+ | AST_TYPE_STRUCT nel_ast ⇒ fold_right_neList … (λt,x.(eval_size_type t)+x) O nel_ast
+ ].
--- /dev/null
+(**************************************************************************)
+(* ___ *)
+(* ||M|| *)
+(* ||A|| A project by Andrea Asperti *)
+(* ||T|| *)
+(* ||I|| Developers: *)
+(* ||T|| The HELM team. *)
+(* ||A|| http://helm.cs.unibo.it *)
+(* \ / *)
+(* \ / This file is distributed under the terms of the *)
+(* v GNU General Public License Version 2 *)
+(* *)
+(**************************************************************************)
+
+(* ********************************************************************** *)
+(* Progetto FreeScale *)
+(* *)
+(* Sviluppato da: Cosimo Oliboni, oliboni@cs.unibo.it *)
+(* Cosimo Oliboni, oliboni@cs.unibo.it *)
+(* *)
+(* ********************************************************************** *)
+
+include "compiler/ast_type.ma".
+include "common/list_utility_lemmas.ma".
+
+(* ************************* *)
+(* dimensioni degli elementi *)
+(* ************************* *)
+
+ndefinition astbasetype_destruct_aux ≝
+Πb1,b2:ast_base_type.ΠP:Prop.b1 = b2 →
+ match b1 with
+ [ AST_BASE_TYPE_BYTE8 ⇒ match b2 with [ AST_BASE_TYPE_BYTE8 ⇒ P → P | _ ⇒ P ]
+ | AST_BASE_TYPE_WORD16 ⇒ match b2 with [ AST_BASE_TYPE_WORD16 ⇒ P → P | _ ⇒ P ]
+ | AST_BASE_TYPE_WORD32 ⇒ match b2 with [ AST_BASE_TYPE_WORD32 ⇒ P → P | _ ⇒ P ]
+ ].
+
+ndefinition astbasetype_destruct : astbasetype_destruct_aux.
+ #b1; #b2; #P;
+ nelim b1;
+ nelim b2;
+ nnormalize;
+ #H;
+ ##[ ##1,5,9: napply (λx:P.x)
+ ##| ##2,3: napply False_ind;
+ nchange with (match AST_BASE_TYPE_BYTE8 with [ AST_BASE_TYPE_BYTE8 ⇒ False | _ ⇒ True]);
+ nrewrite > H;
+ nnormalize;
+ napply I
+ ##| ##4,6: napply False_ind;
+ nchange with (match AST_BASE_TYPE_WORD16 with [ AST_BASE_TYPE_WORD16 ⇒ False | _ ⇒ True]);
+ nrewrite > H;
+ nnormalize;
+ napply I
+ ##| ##7,8: napply False_ind;
+ nchange with (match AST_BASE_TYPE_WORD32 with [ AST_BASE_TYPE_WORD32 ⇒ False | _ ⇒ True]);
+ nrewrite > H;
+ nnormalize;
+ napply I
+ ##]
+nqed.
+
+nlemma symmetric_eqastbasetype : symmetricT ast_base_type bool eq_ast_base_type.
+ #b1; #b2; ncases b1; ncases b2; nnormalize; napply refl_eq. nqed.
+
+nlemma eqastbasetype_to_eq : ∀b1,b2.eq_ast_base_type b1 b2 = true → b1 = b2.
+ #b1; #b2; ncases b1; ncases b2; nnormalize;
+ ##[ ##1,5,9: #H; napply refl_eq
+ ##| ##*: #H; napply (bool_destruct … H)
+ ##]
+nqed.
+
+nlemma eq_to_eqastbasetype : ∀b1,b2.b1 = b2 → eq_ast_base_type b1 b2 = true.
+ #b1; #b2; ncases b1; ncases b2; nnormalize;
+ ##[ ##1,5,9: #H; napply refl_eq
+ ##| ##*: #H; napply (astbasetype_destruct … H)
+ ##]
+nqed.
+
+nlemma asttype_destruct_base_base : ∀b1,b2.AST_TYPE_BASE b1 = AST_TYPE_BASE b2 → b1 = b2.
+ #b1; #b2; #H;
+ nchange with (match AST_TYPE_BASE b2 with [ AST_TYPE_BASE a ⇒ b1 = a | _ ⇒ False ]);
+ nrewrite < H;
+ nnormalize;
+ napply refl_eq.
+nqed.
+
+nlemma asttype_destruct_array_array_1 : ∀x1,x2,y1,y2.AST_TYPE_ARRAY x1 y1 = AST_TYPE_ARRAY x2 y2 → x1 = x2.
+ #x1; #x2; #y1; #y2; #H;
+ nchange with (match AST_TYPE_ARRAY x2 y2 with [ AST_TYPE_ARRAY a _ ⇒ x1 = a | _ ⇒ False ]);
+ nrewrite < H;
+ nnormalize;
+ napply refl_eq.
+nqed.
+
+nlemma asttype_destruct_array_array_2 : ∀x1,x2,y1,y2.AST_TYPE_ARRAY x1 y1 = AST_TYPE_ARRAY x2 y2 → y1 = y2.
+ #x1; #x2; #y1; #y2; #H;
+ nchange with (match AST_TYPE_ARRAY x2 y2 with [ AST_TYPE_ARRAY _ b ⇒ y1 = b | _ ⇒ False ]);
+ nrewrite < H;
+ nnormalize;
+ napply refl_eq.
+nqed.
+
+nlemma asttype_destruct_struct_struct : ∀b1,b2.AST_TYPE_STRUCT b1 = AST_TYPE_STRUCT b2 → b1 = b2.
+ #b1; #b2; #H;
+ nchange with (match AST_TYPE_STRUCT b2 with [ AST_TYPE_STRUCT a ⇒ b1 = a | _ ⇒ False ]);
+ nrewrite < H;
+ nnormalize;
+ napply refl_eq.
+nqed.
+
+ndefinition asttype_destruct_aux ≝
+Πb1,b2:ast_type.ΠP:Prop.b1 = b2 →
+ match b1 with
+ [ AST_TYPE_BASE s1 ⇒ match b2 with
+ [ AST_TYPE_BASE s2 ⇒ match s1 with
+ [ AST_BASE_TYPE_BYTE8 ⇒ match s2 with [ AST_BASE_TYPE_BYTE8 ⇒ P → P | _ ⇒ P ]
+ | AST_BASE_TYPE_WORD16 ⇒ match s2 with [ AST_BASE_TYPE_WORD16 ⇒ P → P | _ ⇒ P ]
+ | AST_BASE_TYPE_WORD32 ⇒ match s2 with [ AST_BASE_TYPE_WORD32 ⇒ P → P | _ ⇒ P ]
+ ] | _ ⇒ P ]
+ | AST_TYPE_ARRAY _ _ ⇒ match b2 with [ AST_TYPE_ARRAY _ _ ⇒ P → P | _ ⇒ P ]
+ | AST_TYPE_STRUCT _ ⇒ match b2 with [ AST_TYPE_STRUCT _ ⇒ P → P | _ ⇒ P ]
+ ].
+
+ndefinition asttype_destruct : asttype_destruct_aux.
+ #b1; #b2; #P;
+ ncases b1;
+ ##[ ##1: ncases b2;
+ ##[ ##1: nnormalize; #s1; #s2; ncases s1; ncases s2; nnormalize;
+ ##[ ##1,5,9: #H; napply (λx:P.x)
+ ##| ##*: #H; napply (astbasetype_destruct … (asttype_destruct_base_base … H))
+ ##]
+ ##| ##2: #t; #n; #b; nnormalize; #H
+ ##| ##3: #l; #b; nnormalize; #H
+ ##]
+ napply False_ind;
+ nchange with (match AST_TYPE_BASE b with [ AST_TYPE_BASE _ ⇒ False | _ ⇒ True ]);
+ nrewrite > H; nnormalize; napply I
+ ##| ##2: ncases b2;
+ ##[ ##2: #t1; #n1; #t2; #n2; nnormalize; #H; napply (λx:P.x)
+ ##| ##1: #b; #t; #n; nnormalize; #H
+ ##| ##3: #l; #t; #n; nnormalize; #H
+ ##]
+ napply False_ind;
+ nchange with (match AST_TYPE_ARRAY t n with [ AST_TYPE_ARRAY _ _ ⇒ False | _ ⇒ True ]);
+ nrewrite > H; nnormalize; napply I
+ ##| ##3: ncases b2;
+ ##[ ##3: #l1; #l2; nnormalize; #H; napply (λx:P.x)
+ ##| ##1: #b; #l; nnormalize; #H
+ ##| ##2: #t; #n; #l; nnormalize; #H
+ ##]
+ napply False_ind;
+ nchange with (match AST_TYPE_STRUCT l with [ AST_TYPE_STRUCT _ ⇒ False | _ ⇒ True ]);
+ nrewrite > H; nnormalize; napply I
+ ##]
+nqed.
+
+nlemma symmetric_eqasttype_aux1
+ : ∀nl1,nl2.
+ (eq_ast_type (AST_TYPE_STRUCT nl1) (AST_TYPE_STRUCT nl2)) = (eq_ast_type (AST_TYPE_STRUCT nl2) (AST_TYPE_STRUCT nl1)) →
+ (bfold_right_neList2 ? (λx,y.eq_ast_type x y) nl1 nl2) = (bfold_right_neList2 ? (λx,y.eq_ast_type x y) nl2 nl1).
+ #nl1; #nl2; #H;
+ napply H.
+nqed.
+
+nlemma symmetric_eqasttype : symmetricT ast_type bool eq_ast_type.
+ #t1; napply (ast_type_index … t1);
+ ##[ ##1: #b1; #t2; ncases t2;
+ ##[ ##1: #b2; nchange with ((eq_ast_base_type b1 b2) = (eq_ast_base_type b2 b1));
+ nrewrite > (symmetric_eqastbasetype b1 b2);
+ napply refl_eq
+ ##| ##2: #st2; #n2; nnormalize; napply refl_eq
+ ##| ##3: #nl2; nnormalize; napply refl_eq
+ ##]
+ ##| ##2: #st1; #n1; #H; #t2; ncases t2;
+ ##[ ##2: #st2; #n2; nchange with (((eq_ast_type st1 st2)⊗(eq_nat n1 n2)) = ((eq_ast_type st2 st1)⊗(eq_nat n2 n1)));
+ nrewrite > (symmetric_eqnat n1 n2);
+ nrewrite > (H st2);
+ napply refl_eq
+ ##| ##1: #b2; nnormalize; napply refl_eq
+ ##| ##3: #nl2; nnormalize; napply refl_eq
+ ##]
+ ##| ##3: #hh1; #H; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; nchange with ((eq_ast_type hh1 hh2) = (eq_ast_type hh2 hh1));
+ nrewrite > (H hh2);
+ napply refl_eq
+ ##| ##2: #hh2; #ll2; nnormalize; napply refl_eq
+ ##]
+ ##| ##1: #b2; nnormalize; napply refl_eq
+ ##| ##2: #st2; #n2; nnormalize; napply refl_eq
+ ##]
+ ##| ##4: #hh1; #ll1; #H; #H1; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; nnormalize; napply refl_eq
+ ##| ##2: #hh2; #ll2; nnormalize;
+ nrewrite > (H hh2);
+ nrewrite > (symmetric_eqasttype_aux1 ll1 ll2 (H1 (AST_TYPE_STRUCT ll2)));
+ napply refl_eq
+ ##]
+ ##| ##1: #b2; nnormalize; napply refl_eq
+ ##| ##2: #st2; #n2; nnormalize; napply refl_eq
+ ##]
+ ##]
+nqed.
+
+nlemma eqasttype_to_eq : ∀t1,t2.eq_ast_type t1 t2 = true → t1 = t2.
+ #t1;
+ napply (ast_type_index … t1);
+ ##[ ##1: #b1; #t2; ncases t2;
+ ##[ ##1: #b2; #H; nchange in H:(%) with ((eq_ast_base_type b1 b2) = true);
+ nrewrite > (eqastbasetype_to_eq b1 b2 H);
+ napply refl_eq
+ ##| ##2: #st2; #n2; nnormalize; #H; napply (bool_destruct … H)
+ ##| ##3: #nl2; nnormalize; #H; napply (bool_destruct … H)
+ ##]
+ ##| ##2: #st1; #n1; #H; #t2; ncases t2;
+ ##[ ##2: #st2; #n2; #H1; nchange in H1:(%) with (((eq_ast_type st1 st2)⊗(eq_nat n1 n2)) = true);
+ nrewrite > (H st2 (andb_true_true_l … H1));
+ nrewrite > (eqnat_to_eq n1 n2 (andb_true_true_r … H1));
+ napply refl_eq
+ ##| ##1: #b2; nnormalize; #H1; napply (bool_destruct … H1)
+ ##| ##3: #nl2; nnormalize; #H1; napply (bool_destruct … H1)
+ ##]
+ ##| ##3: #hh1; #H; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; #H1; nchange in H1:(%) with ((eq_ast_type hh1 hh2) = true);
+ nrewrite > (H hh2 H1);
+ napply refl_eq
+ ##| ##2: #hh2; #ll2; nnormalize; #H1; napply (bool_destruct … H1)
+ ##]
+ ##| ##1: #b2; nnormalize; #H1; napply (bool_destruct … H1)
+ ##| ##2: #st2; #n2; nnormalize; #H1; napply (bool_destruct … H1)
+ ##]
+ ##| ##4: #hh1; #ll1; #H; #H1; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; nnormalize; #H2; napply (bool_destruct … H2)
+ ##| ##2: #hh2; #ll2; #H2; nchange in H2:(%) with (((eq_ast_type hh1 hh2)⊗(bfold_right_neList2 ? (λx,y.eq_ast_type x y) ll1 ll2)) = true);
+ nrewrite > (H hh2 (andb_true_true_l … H2));
+ nrewrite > (asttype_destruct_struct_struct ll1 ll2 (H1 (AST_TYPE_STRUCT ll2) (andb_true_true_r … H2)));
+ napply refl_eq
+ ##]
+ ##| ##1: #b2; nnormalize; #H2; napply (bool_destruct … H2)
+ ##| ##2: #st2; #n2; nnormalize; #H2; napply (bool_destruct … H2)
+ ##]
+ ##]
+nqed.
+
+nlemma eq_to_eqasttype_aux1
+ : ∀nl1,nl2.
+ ((eq_ast_type (AST_TYPE_STRUCT nl1) (AST_TYPE_STRUCT nl2)) = true) →
+ ((bfold_right_neList2 ? (λx,y.eq_ast_type x y) nl1 nl2) = true).
+ #nl1; #nl2; #H;
+ napply H.
+nqed.
+
+nlemma eq_to_eqasttype : ∀t1,t2.t1 = t2 → eq_ast_type t1 t2 = true.
+ #t1;
+ napply (ast_type_index … t1);
+ ##[ ##1: #b1; #t2; ncases t2;
+ ##[ ##1: #b2; #H; nrewrite > (asttype_destruct_base_base … H);
+ nchange with ((eq_ast_base_type b2 b2) = true);
+ nrewrite > (eq_to_eqastbasetype b2 b2 (refl_eq …));
+ napply refl_eq
+ ##| ##2: #st2; #n2; #H; napply (asttype_destruct … H)
+ ##| ##3: #nl2; #H; napply (asttype_destruct … H)
+ ##]
+ ##| ##2: #st1; #n1; #H; #t2; ncases t2;
+ ##[ ##2: #st2; #n2; #H1; nchange with (((eq_ast_type st1 st2)⊗(eq_nat n1 n2)) = true);
+ nrewrite > (H st2 (asttype_destruct_array_array_1 … H1));
+ nrewrite > (eq_to_eqnat n1 n2 (asttype_destruct_array_array_2 … H1));
+ nnormalize;
+ napply refl_eq
+ ##| ##1: #b2; #H1; napply (asttype_destruct … H1)
+ ##| ##3: #nl2; #H1; napply (asttype_destruct … H1)
+ ##]
+ ##| ##3: #hh1; #H; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; #H1; nchange with ((eq_ast_type hh1 hh2) = true);
+ nrewrite > (H hh2 (nelist_destruct_nil_nil ? hh1 hh2 (asttype_destruct_struct_struct … H1)));
+ napply refl_eq
+ ##| ##2: #hh2; #ll2; #H1; nelim (nelist_destruct_nil_cons ? hh1 hh2 ll2 (asttype_destruct_struct_struct … H1))
+ ##]
+ ##| ##1: #b2; #H1; napply (asttype_destruct … H1)
+ ##| ##2: #st2; #n2; #H1; napply (asttype_destruct … H1)
+ ##]
+ ##| ##4: #hh1; #ll1; #H; #H1; #t2; ncases t2;
+ ##[ ##3: #nl2; ncases nl2;
+ ##[ ##1: #hh2; #H2; nelim (nelist_destruct_cons_nil ? hh1 hh2 ll1 (asttype_destruct_struct_struct … H2))
+ ##| ##2: #hh2; #ll2; #H2; nchange with (((eq_ast_type hh1 hh2)⊗(bfold_right_neList2 ? (λx,y.eq_ast_type x y) ll1 ll2)) = true);
+ nrewrite > (H hh2 (nelist_destruct_cons_cons_1 … (asttype_destruct_struct_struct … H2)));
+ nrewrite > (eq_to_eqasttype_aux1 ll1 ll2 (H1 (AST_TYPE_STRUCT ll2) ?));
+ ##[ ##1: nnormalize; napply refl_eq
+ ##| ##2: nrewrite > (nelist_destruct_cons_cons_2 … (asttype_destruct_struct_struct … H2));
+ napply refl_eq
+ ##]
+ ##]
+ ##| ##1: #b2; #H2; napply (asttype_destruct … H2)
+ ##| ##2: #st2; #n2; #H2; napply (asttype_destruct … H2)
+ ##]
+ ##]
+nqed.
+
+nlemma isbastbasetype_to_isastbasetype : ∀ast.isb_ast_base_type ast = true → is_ast_base_type ast.
+ #ast;
+ ncases ast;
+ nnormalize;
+ ##[ ##1: #t; #H; napply I
+ ##| ##2: #t; #n; #H; napply (bool_destruct … H)
+ ##| ##3: #t; #H; napply (bool_destruct … H)
+ ##]
+nqed.
+
+nlemma isntbastbasetype_to_isntastbasetype : ∀ast.isntb_ast_base_type ast = true → isnt_ast_base_type ast.
+ #ast;
+ ncases ast;
+ nnormalize;
+ ##[ ##1: #t; #H; napply (bool_destruct … H)
+ ##| ##2: #t; #n; #H; napply I
+ ##| ##3: #l; #H; napply I
+ ##]
+nqed.