Ltac _destruct_var_types i Heq_vt Heq_ve t b :=
let HH := fresh "H" in
match goal with
| H: typecheck_var_environ _ _ |- _ =>
pose proof WARNING___________you_should_use_tactic___destruct_var_types___instead _ _ H i as HH
| H: typecheck_environ _ _ |- _ =>
pose proof WARNING___________you_should_use_tactic___destruct_var_types___instead _ _ (proj1 (proj2 H)) i as HH
end;
match type of HH with
| match ?o with _ => _ end =>
match goal with
| H: o = Some _ |- _ =>
rewrite H in HH
| H: Some _ = o |- _ =>
rewrite <- H in HH
| H: o = None |- _ =>
rewrite H in HH
| H: None = o |- _ =>
rewrite <- H in HH
| _ =>
let HH' := fresh "H" in
pose proof eq_refl o as HH';
destruct o as [t |] in HH, HH' at 2;
pose proof HH' as Heq_vt; clear HH'
end
end;
match type of HH with
| ex _ =>
pose proof HH as [b Heq_ve]
| _ =>
pose proof HH as Heq_ve
end;
clear HH.
Tactic Notation "destruct_var_types" constr(i) :=
let Heq_vt := fresh "Heqo" in
let Heq_ve := fresh "Heqo" in
let t := fresh "t" in
let b := fresh "b" in
_destruct_var_types i Heq_vt Heq_ve t b.
Tactic Notation "destruct_var_types" constr(i) "as" "[" ident(t) ident(b) "]" :=
let Heq_vt := fresh "Heqo" in
let Heq_ve := fresh "Heqo" in
_destruct_var_types i Heq_vt Heq_ve t b.
Tactic Notation "destruct_var_types" constr(i) "eqn" ":" simple_intropattern(Heq_vt) "&" simple_intropattern(Heq_ve) :=
let t := fresh "t" in
let b := fresh "b" in
_destruct_var_types i Heq_vt Heq_ve t b.
Tactic Notation "destruct_var_types" constr(i) "as" "[" ident(t) ident(b) "]" "eqn" ":" simple_intropattern(Heq_vt) "&" simple_intropattern(Heq_ve) :=
_destruct_var_types i Heq_vt Heq_ve t b.
Ltac _destruct_glob_types i Heq_gt Heq_ge t b :=
let HH := fresh "H" in
match goal with
| H: typecheck_glob_environ _ _ |- _ =>
pose proof WARNING___________you_should_use_tactic___destruct_glob_types___instead _ _ H i as HH
| H: typecheck_environ _ _ |- _ =>
pose proof WARNING___________you_should_use_tactic___destruct_glob_types___instead _ _ (proj2 (proj2 H)) i as HH
end;
match type of HH with
| match ?o with _ => _ end =>
match goal with
| H: o = Some _ |- _ =>
rewrite H in HH
| H: Some _ = o |- _ =>
rewrite <- H in HH
| H: o = None |- _ =>
rewrite H in HH
| H: None = o |- _ =>
rewrite <- H in HH
| _ =>
let HH' := fresh "H" in
pose proof eq_refl o as HH';
destruct o as [t |] in HH, HH' at 2;
pose proof HH' as Heq_gt; clear HH'
end
end;
match type of HH with
| ex _ =>
pose proof HH as [b Heq_ge]
| _ =>
idtac
end;
clear HH.
Tactic Notation "destruct_glob_types" constr(i) :=
let Heq_gt := fresh "Heqo" in
let Heq_ge := fresh "Heqo" in
let t := fresh "t" in
let b := fresh "b" in
_destruct_glob_types i Heq_gt Heq_ge t b.
Tactic Notation "destruct_glob_types" constr(i) "as" "[" ident(t) ident(b) "]" :=
let Heq_gt := fresh "Heqo" in
let Heq_ge := fresh "Heqo" in
_destruct_glob_types i Heq_gt Heq_ge t b.
Tactic Notation "destruct_glob_types" constr(i) "eqn" ":" simple_intropattern(Heq_gt) "&" simple_intropattern(Heq_ge) :=
let t := fresh "t" in
let b := fresh "b" in
_destruct_glob_types i Heq_gt Heq_ge t b.
Tactic Notation "destruct_glob_types" constr(i) "as" "[" ident(t) ident(b) "]" "eqn" ":" simple_intropattern(Heq_gt) "&" simple_intropattern(Heq_ge) :=
_destruct_glob_types i Heq_gt Heq_ge t b.
(** Type-checking of function parameters **)
Fixpoint match_fsig_aux (bl: list expr) (tl: list (ident*type)) : bool :=
match bl, tl with
| b::bl', (_,t'):: tl' => if eqb_type (typeof b) t' then match_fsig_aux bl' tl' else false
| nil, nil => true
| nil, _::_ => false
| _::_, nil => false
end.
Definition match_fsig (fs: funsig) (bl: list expr) (ret: option ident) : bool :=
andb (match_fsig_aux bl (fst fs))
(match snd fs, ret with
| Tvoid , None => true
| Tvoid, Some _ => false
| _, None => false
| _, Some _ => true
end).

(* Specifications: *)
Lemma match_fsig_e: forall fs bl ret,
match_fsig fs bl ret = true ->
map typeof bl = map (@snd _ _) (fst fs) /\ (snd fs=Tvoid <-> ret=None).