Ltac intro_redundant_prop :=
(* do it in this complicated way because the proof will come out smaller *)
match goal with |- ?P -> _ =>
((assert P by immediate; fail 1) || fail 1) || intros _
end.
Ltac fancy_intro aggressive :=
match goal with
| |- ?P -> _ => match type of P with Prop => idtac end
| |- ~ _ => idtac
end;
let H := fresh in
intro H;
try simple apply ptr_eq_e in H;
try simple apply Vint_inj in H;
try match type of H with
| tc_val _ _ => unfold tc_val in H; try change (eqb_type _ _) with false in H; cbv iota in H
end;
match type of H with
| ?P => clear H;
match goal with H': P |- _ => idtac end (* work around bug number 6998 in Coq *)
+ (((assert (H:P) by (clear; immediate); fail 1) || fail 1) || idtac)
(* do it in this complicated way because the proof will come out smaller *)
| ?x = ?y => constr_eq aggressive true;
first [subst x | subst y
| is_var x; rewrite H
| is_var y; rewrite <- H
| idtac]
| headptr (_ ?x) => let Hx1 := fresh "HP" x in
let Hx2 := fresh "P" x in
rename H into Hx1;
pose proof headptr_isptr _ Hx1 as Hx2
| headptr ?x => let Hx1 := fresh "HP" x in
let Hx2 := fresh "P" x in
rename H into Hx1;
pose proof headptr_isptr _ Hx1 as Hx2
| isptr ?x => let Hx := fresh "P" x in rename H into Hx
| is_pointer_or_null ?x => let Hx := fresh "PN" x in rename H into Hx
| typed_false _ _ =>
first [simple apply typed_false_of_bool in H
| apply typed_false_tint_Vint in H
| apply (typed_false_tint (eq_refl _)) in H
| apply (typed_false_tlong (eq_refl _)) in H
| apply typed_false_ptr in H
| idtac ]
| typed_true _ _ =>
first [simple apply typed_true_of_bool in H
| apply typed_true_tint_Vint in H
| apply typed_true_tlong_Vlong in H
(*  This one is not portable 32/64 bits | apply (typed_true_e tint) in H *)
| apply typed_true_ptr in H
| idtac ]
(* | locald_denote _ _ => hnf in H *)
| _ => try solve [discriminate H]
end.
Ltac fancy_intros aggressive :=
repeat match goal with
| |- (_ <= _ < _) -> _ => fancy_intro aggressive
| |- (_ < _ <= _) -> _ => fancy_intro aggressive
| |- (_ <= _ <= _) -> _ => fancy_intro aggressive
| |- (_ < _ < _) -> _ => fancy_intro aggressive
| |- (?A /\ ?B) -> ?C => apply (@and_ind A B C) (* For some reason "apply and_ind" doesn't work the same *)
| |- _ -> _ => fancy_intro aggressive
end.
Ltac fold_types :=
fold noattr tuint tint tschar tuchar;
repeat match goal with
| |- context [Tpointer ?t noattr] =>
change (Tpointer t noattr) with (tptr t)
| |- context [Tarray ?t ?n noattr] =>
change (Tarray t n noattr) with (tarray t n)
end.
Ltac fold_types1 :=
match goal with |- _ -> ?A =>
let a := fresh "H" in set (a:=A); fold_types; subst a
end.

Lemma is_int_Vbyte: forall c, is_int I8 Signed (Vbyte c).
Hint Resolve is_int_Vbyte.