Library expr_lemmas
Require Import msl.msl_standard.
Require Import veric.base.
Require Import msl.rmaps.
Require Import msl.rmaps_lemmas.
Require Import veric.compcert_rmaps.
Require Import veric.Clight_lemmas.
Require Import veric.expr.
Require Export veric.environ_lemmas.
Require Import veric.binop_lemmas.
Import Cop.
Opaque tc_andp.
Require Import veric.base.
Require Import msl.rmaps.
Require Import msl.rmaps_lemmas.
Require Import veric.compcert_rmaps.
Require Import veric.Clight_lemmas.
Require Import veric.expr.
Require Export veric.environ_lemmas.
Require Import veric.binop_lemmas.
Import Cop.
Opaque tc_andp.
Definitions of some environments
Definition empty_genv := (Globalenvs.Genv.empty_genv fundef type).
Definition empty_tenv := PTree.empty val.
Definition empty_environ : environ :=
mkEnviron (filter_genv empty_genv) (Map.empty _) (Map.empty _).
Definition Delta1 : tycontext := (PTree.set 1%positive (type_int32s, false)
(PTree.empty (type * bool)),
PTree.empty type, Tvoid,PTree.empty _).
Lemma Zle_bool_rev: forall x y, Zle_bool x y = Zge_bool y x.
Proof.
intros. pose proof (Zle_cases x y). pose proof (Zge_cases y x).
destruct (Zle_bool x y); destruct (Zge_bool y x); auto;
elimtype False; omega.
Qed.
Lemma type_eq_true : forall a b, proj_sumbool (type_eq a b) =true -> a = b.
Proof. intros. destruct (type_eq a b). auto. simpl in H. inv H.
Qed.
Definition empty_tenv := PTree.empty val.
Definition empty_environ : environ :=
mkEnviron (filter_genv empty_genv) (Map.empty _) (Map.empty _).
Definition Delta1 : tycontext := (PTree.set 1%positive (type_int32s, false)
(PTree.empty (type * bool)),
PTree.empty type, Tvoid,PTree.empty _).
Lemma Zle_bool_rev: forall x y, Zle_bool x y = Zge_bool y x.
Proof.
intros. pose proof (Zle_cases x y). pose proof (Zge_cases y x).
destruct (Zle_bool x y); destruct (Zge_bool y x); auto;
elimtype False; omega.
Qed.
Lemma type_eq_true : forall a b, proj_sumbool (type_eq a b) =true -> a = b.
Proof. intros. destruct (type_eq a b). auto. simpl in H. inv H.
Qed.
Typechecking soundness
Lemma eval_lvalue_ptr : forall rho e (Delta: tycontext) te ve ge,
mkEnviron ge ve te = rho ->
typecheck_var_environ ve (var_types Delta) ->
typecheck_glob_environ ge (glob_types Delta) ->
denote_tc_assert (typecheck_lvalue Delta e) rho ->
eval_lvalue e rho = Vundef \/ exists base, exists ofs, eval_lvalue e rho = Vptr base ofs.
Proof.
intros.
induction e; eauto.
simpl. unfold eval_var.
remember (Map.get (ve_of rho) i). destruct o; try rewrite eqb_type_eq; intuition;
try destruct p; try rewrite eqb_type_eq; simpl; try remember (type_eq t t0); try destruct s;
simpl; try remember (negb (type_is_volatile t0));try destruct b0; auto;
try solve[right; eauto].
remember (ge_of rho i); try rewrite eqb_type_eq; simpl.
destruct o; try rewrite eqb_type_eq; simpl; eauto.
destruct p; try rewrite eqb_type_eq; simpl; eauto.
if_tac; eauto.
unfold typecheck_var_environ in *. simpl in H2.
unfold get_var_type in *.
remember ((var_types Delta) ! i).
destruct o. subst. simpl in H2.
super_unfold_lift.
try rewrite eqb_type_eq in *; simpl in *; intuition.
symmetry in Heqo1.
specialize (H0 i t1 Heqo1).
destruct H0. congruence.
remember ((glob_types Delta) ! i). destruct o; simpl in *; try congruence.
super_unfold_lift. right.
unfold typecheck_glob_environ in H1.
symmetry in Heqo2.
specialize (H1 _ _ Heqo2). destruct H1 as [b [i0 [? ?]]].
rewrite <- H in *. simpl ge_of in Heqo0. rewrite H1 in *.
inv Heqo0. eauto. inv H2.
simpl in *. intuition. super_unfold_lift. unfold force_ptr in *.
destruct (eval_expr e rho); eauto.
simpl in *. super_unfold_lift.
rewrite tc_andp_sound in *. simpl in *.
super_unfold_lift. rewrite tc_andp_sound in *.
simpl in *. super_unfold_lift.
destruct H2 as [[? ?] ?].
spec IHe; auto. destruct IHe.
unfold eval_field.
destruct (eval_lvalue e rho); eauto;
destruct (typeof e); try congruence; auto.
destruct (field_offset i f); eauto.
unfold eval_field.
destruct (eval_lvalue e rho); eauto;
destruct (typeof e); try congruence; auto;
try destruct (field_offset i f); eauto.
destruct (field_offset i f0); eauto.
unfold offset_val; right; eauto.
Qed.
Transparent Float.intoffloat.
Transparent Float.intuoffloat.
Ltac unfold_tc_denote :=
unfold denote_tc_nonzero in *;
unfold isptr in *;
unfold denote_tc_igt in *;
unfold denote_tc_Zle in *;
unfold denote_tc_Zge in *;
unfold denote_tc_samebase in *;
unfold denote_tc_nodivover in *;
unfold denote_tc_initialized in *.
Lemma typecheck_lvalue_Evar:
forall i t pt Delta rho, typecheck_environ Delta rho ->
denote_tc_assert (typecheck_lvalue Delta (Evar i t)) rho ->
is_pointer_type pt = true ->
typecheck_val (eval_lvalue (Evar i t) rho) pt = true.
Proof.
intros.
simpl in *. unfold eval_var.
unfold typecheck_environ in H.
intuition.
destruct rho.
unfold typecheck_var_environ in *. unfold get_var_type in *.
remember ((var_types Delta) ! i).
destruct o; try rewrite eqb_type_eq in *; simpl in *; intuition.
super_unfold_lift.
remember (type_eq t t0). destruct s; intuition.
subst. remember (negb(type_is_volatile t0)).
rewrite tc_andp_sound in *. simpl in *. super_unfold_lift.
destruct b; intuition.
clear H3. symmetry in Heqo.
specialize (H i t0 Heqo).
{destruct H.
rewrite H in *. rewrite <- Heqb. rewrite eqb_type_refl in *. destruct pt; auto.
}
{remember ((glob_types Delta) ! i). destruct o; try congruence.
rewrite tc_andp_sound in *. simpl in *.
simpl in *. super_unfold_lift. destruct H0. remember (eqb_type t (globtype g)).
symmetry in Heqb. destruct b; simpl in *; try congruence. apply eqb_type_true in Heqb.
subst.
unfold same_env in *.
symmetry in Heqo0. specialize (H5 _ _ Heqo0).
destruct H5. simpl in *. unfold Map.get. rewrite H5.
unfold typecheck_glob_environ in *. destruct (H3 i g); auto. destruct H6. destruct H6.
rewrite H6. rewrite eqb_type_refl. auto.
destruct pt; inv H1; reflexivity.
destruct H5; congruence. inv H0.
inv H0.
}
Qed.
Lemma typecheck_expr_sound_Efield:
forall Delta rho e i t
(H: typecheck_environ Delta rho)
(IHe: (denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt : type,
denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt = true ->
typecheck_val (eval_lvalue e rho) pt = true))
(H0: denote_tc_assert (typecheck_expr Delta (Efield e i t)) rho),
typecheck_val (eval_expr (Efield e i t) rho) (typeof (Efield e i t)) = true.
Proof.
intros.
simpl in *. super_unfold_lift.
unfold eval_field, offset_val, deref_noload in *.
assert (MODE: access_mode t = By_reference) by (destruct (access_mode t); auto; hnf in H0; try contradiction).
rewrite MODE in *.
destruct IHe.
destruct rho.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
simpl in H0.
super_unfold_lift. destruct H0 as [[? ]?].
revert H4; case_eq (type_is_volatile t); simpl; intros; try contradiction.
clear H5.
unfold typecheck_environ in H.
destruct H as [_ [Hve [Hge _]]].
assert (PTR := eval_lvalue_ptr _ e Delta te ve ge (eq_refl _) Hve Hge H0).
specialize (H2 t H0).
spec H2. clear - MODE; destruct t; try destruct i; try destruct s; try destruct f; inv MODE; simpl; auto.
destruct PTR.
elimtype False; clear - H H2. rewrite H in H2; inv H2.
destruct H as [b [ofs ?]].
rewrite H in *.
destruct (typeof e); intuition.
destruct (field_offset i f); intuition.
Qed.
Lemma typecheck_lvalue_sound_Efield:
forall Delta rho e i t pt
(H: typecheck_environ Delta rho)
(IHe: (denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt0 : type, denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt0 = true ->
typecheck_val (eval_lvalue e rho) pt0 = true))
(H0: denote_tc_assert (typecheck_lvalue Delta (Efield e i t)) rho)
(H1: is_pointer_type pt = true),
typecheck_val (eval_lvalue (Efield e i t) rho) pt = true.
Proof.
intros.
simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift.
unfold eval_field,offset_val in *; intuition.
specialize (H3 pt). intuition. remember rho.
destruct e0.
unfold typecheck_environ in *. intuition. clear H4 H9.
rewrite Heqe0 in H0.
assert (PTR := eval_lvalue_ptr _ e _ _ _ _ Heqe0 H H7).
rewrite Heqe0 in *. clear Heqe0.
intuition.
remember (eval_lvalue e rho). unfold isptr in *.
destruct v; intuition; try congruence.
remember (eval_lvalue e rho). destruct H8. destruct H4.
destruct v; intuition; try congruence.
inv H4.
destruct (typeof e); intuition.
destruct (field_offset i f); intuition.
Qed.
Lemma typecheck_expr_sound_Evar:
forall Delta rho i t,
typecheck_environ Delta rho ->
denote_tc_assert (typecheck_expr Delta (Evar i t)) rho ->
typecheck_val (eval_expr (Evar i t) rho) (typeof (Evar i t)) = true.
Proof.
intros.
assert (MODE: access_mode t = By_reference)
by (unfold typecheck_expr in H0; destruct (access_mode t); try (hnf in H0; contradiction); auto).
simpl. super_unfold_lift. unfold deref_noload. rewrite MODE.
unfold typecheck_environ in H. intuition.
rename H4 into SM.
destruct rho.
unfold typecheck_var_environ, same_env in *.
simpl in H0. rewrite MODE in H0.
unfold get_var_type in *.
remember ((var_types Delta) ! i).
destruct o; try rewrite eqb_type_eq in *; simpl in *; intuition.
remember (type_eq t t0). destruct s; intuition.
subst. simpl in H0.
remember (negb(type_is_volatile t0)). destruct b; intuition.
clear H0.
symmetry in Heqo.
specialize (H i t0 Heqo).
destruct H. unfold eval_var. simpl.
rewrite H in *. rewrite <- Heqb. rewrite eqb_type_refl in *.
simpl. destruct t0; try destruct i0; try destruct s; try destruct f; inv MODE; auto.
remember ((glob_types Delta) ! i). destruct o; try congruence.
simpl in *.
rewrite tc_andp_sound in *. simpl in *.
unfold eval_var in *.
super_unfold_lift. destruct H0. remember (eqb_type t (globtype g)).
symmetry in Heqb. destruct b; simpl in *; try congruence. apply eqb_type_true in Heqb.
subst.
symmetry in Heqo0. specialize (SM _ _ Heqo0).
destruct SM.
unfold Map.get. rewrite H4.
unfold typecheck_glob_environ in *.
destruct (H2 i g); auto. destruct H5; destruct H5.
rewrite H5. rewrite eqb_type_refl. auto. destruct H4; congruence.
inv H0. inv H0.
Qed.
Lemma typecheck_unop_sound:
forall Delta rho u e t
(H: typecheck_environ Delta rho)
(IHe: (denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt : type,
denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt = true ->
typecheck_val (eval_lvalue e rho) pt = true))
(H0: denote_tc_assert (typecheck_expr Delta (Eunop u e t)) rho),
typecheck_val (eval_expr (Eunop u e t) rho) (typeof (Eunop u e t)) = true.
Proof.
intros.
simpl in H0. rewrite denote_tc_assert_andp in H0. destruct H0.
destruct IHe as [? _].
specialize (H2 H1).
simpl eval_expr.
unfold_lift.
clear - H2 H0.
revert H0; case_eq (isUnOpResultType u e t); intros; [ | inv H0].
clear H0.
simpl.
forget (eval_expr e rho) as v.
clear - H2 H.
assert (TV: forall b i s a, typecheck_val (Val.of_bool b) (Tint i s a) = true)
by (destruct b; reflexivity).
unfold isUnOpResultType in H.
unfold eval_unop, sem_unary_operation.
unfold classify_bool in H.
destruct u; try solve [inv H]; simpl.
assert (is_int_type t = true)
by (destruct (typeof e); try destruct i,s; inv H; auto).
destruct t; inv H0.
unfold sem_notbool.
destruct (typeof e), v; inv H2; try destruct i0,s0; simpl; inv H; try rewrite H1; auto.
unfold sem_notint.
destruct (typeof e), v; inv H; inv H2; simpl; auto.
destruct i,s; destruct t; inv H1; simpl; auto.
unfold sem_neg; simpl.
destruct (typeof e); inv H.
destruct v; inv H2.
destruct i,s; inv H1; simpl; destruct t; try inv H0; auto.
destruct v; inv H2.
destruct f; inv H1; simpl; destruct t; try inv H0; auto.
Qed.
Lemma isCastR: forall tfrom tto ty a,
denote_tc_assert (isCastResultType tfrom tto ty a) =
denote_tc_assert
match Cop.classify_cast tfrom tto with
| Cop.cast_case_default => tc_FF (invalid_cast tfrom tto)
| Cop.cast_case_f2i _ Signed => tc_andp (tc_Zge a Int.min_signed ) (tc_Zle a Int.max_signed)
| Cop.cast_case_f2i _ Unsigned => tc_andp (tc_Zge a 0) (tc_Zle a Int.max_unsigned)
| Cop.cast_case_neutral => if eqb_type tfrom ty then tc_TT else
(if orb (andb (is_pointer_type ty) (is_pointer_type tfrom)) (andb (is_int_type ty) (is_int_type tfrom)) then tc_TT
else tc_iszero' a)
| Cop.cast_case_void => tc_noproof
| _ => match tto with
| Tint _ _ _ => tc_bool (is_int_type ty) (invalid_cast_result tto ty)
| Tfloat _ _ => tc_bool (is_float_type ty) (invalid_cast_result tto ty)
| _ => tc_FF (invalid_cast tfrom tto)
end
end.
Proof. intros; extensionality rho.
unfold isCastResultType.
destruct (classify_cast tfrom tto); auto.
destruct (eqb_type tfrom ty); auto.
if_tac; auto. apply denote_tc_assert_iszero.
Qed.
Lemma typecheck_cast_sound:
forall Delta rho e t,
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt : type,
denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt = true -> typecheck_val (eval_lvalue e rho) pt = true) ->
denote_tc_assert (typecheck_expr Delta (Ecast e t)) rho ->
typecheck_val (eval_expr (Ecast e t) rho) (typeof (Ecast e t)) = true.
Proof.
intros until t; intros H IHe H0.
simpl in *. unfold_lift.
destruct IHe as [? _].
rewrite denote_tc_assert_andp in H0.
destruct H0.
specialize (H1 H0).
unfold eval_cast, sem_cast.
rewrite isCastR in H2.
revert H2; case_eq (classify_cast (typeof e) t); intros;
try solve [destruct t; try contradiction;
destruct (eval_expr e rho), (typeof e); inv H2; inv H1; simpl; auto; destruct i; inv H5].
remember (eval_expr e rho) as v.
destruct (typeof e), v, t; inv H1; inv H2; auto;
simpl in H3; unfold_lift in H3; try reflexivity;
try solve [hnf in H3; rewrite <- Heqv in H3; apply H3];
try solve [destruct i,s; inv H4];
try solve [destruct i0; inv H4];
try solve [rewrite <- Heqv in H3; inv H3].
destruct si2.
rewrite denote_tc_assert_andp in H3. destruct H3.
hnf in H3,H4. unfold_lift in H3; unfold_lift in H4; hnf in H3,H4.
destruct (eval_expr e rho); try contradiction.
simpl. unfold Float.intoffloat. destruct (Float.Zoffloat f); try contradiction.
hnf in H3,H4. rewrite H3.
simpl. rewrite Zle_bool_rev. rewrite H4. simpl.
destruct (typeof e); inv H1.
destruct t; inv H2; auto.
rewrite denote_tc_assert_andp in H3. destruct H3.
hnf in H3,H4. unfold_lift in H3; unfold_lift in H4; hnf in H3,H4.
destruct (eval_expr e rho); try contradiction.
simpl. unfold Float.intuoffloat. destruct (Float.Zoffloat f); try contradiction.
hnf in H3,H4. rewrite H3.
simpl. rewrite Zle_bool_rev. rewrite H4. simpl.
destruct (typeof e); inv H1.
destruct t; inv H2; auto.
Qed.
Lemma same_base_tc_val : forall v t1 t2,
same_base_type t1 t2 = true ->
typecheck_val v t1 = typecheck_val v t2.
Proof.
intros. destruct v; destruct t1; destruct t2; try solve [inv H]; auto.
Qed.
Lemma typecheck_temp_sound:
forall Delta rho i t,
typecheck_environ Delta rho ->
denote_tc_assert (typecheck_expr Delta (Etempvar i t)) rho ->
typecheck_val (eval_expr (Etempvar i t) rho) (typeof (Etempvar i t)) = true.
Proof.
intros.
simpl in *. destruct rho.
destruct H as [H1 _].
unfold typecheck_temp_environ in *.
unfold eval_id, force_val in *.
simpl.
destruct Delta as [[[? ?] ?] ?]. simpl in *.
unfold temp_types in *. simpl in *.
specialize (H1 i).
destruct (type_is_volatile t); simpl in H0; unfold lift in H0; try contradiction.
destruct (t0 ! i); try (contradiction H0).
destruct p. destruct (H1 _ _ (eq_refl _)) as [v [? ?]]. clear H1.
rewrite H.
simpl in H0.
remember (same_base_type t t4).
destruct b0; [ | inv H0].
simpl in H0.
destruct b; inv H0;
intuition;
erewrite same_base_tc_val; eauto.
simpl in H0. rewrite H in H0. inv H0.
erewrite <- same_base_tc_val; eauto.
Qed.
Lemma typecheck_deref_sound:
forall Delta rho e t pt,
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt0 : type,
denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt0 = true -> typecheck_val (eval_lvalue e rho) pt0 = true) ->
denote_tc_assert (typecheck_lvalue Delta (Ederef e t)) rho ->
is_pointer_type pt = true ->
typecheck_val (eval_lvalue (Ederef e t) rho) pt = true.
Proof.
intros until pt. intros H IHe H0 H1.
simpl. unfold lift.
simpl in H0.
repeat rewrite denote_tc_assert_andp in H0.
destruct H0 as [[[? ?] ?] ?].
destruct IHe as[ ? _].
specialize (H5 H0).
revert H2; case_eq (is_pointer_type (typeof e)); intros; hnf in H2; try contradiction.
clear H H6 H4.
hnf in H3. unfold_lift in H3; hnf in H3.
unfold_lift.
destruct (eval_expr e rho); try contradiction.
destruct pt; inv H1; reflexivity.
Qed.
Main soundness result for the typechecker
Lemma typecheck_both_sound:
forall Delta rho e ,
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true) /\
(forall pt,
denote_tc_assert (typecheck_lvalue Delta e) rho ->
is_pointer_type pt = true ->
typecheck_val (eval_lvalue e rho) pt=true).
Proof.
intros. induction e; split; intros; try solve[subst; auto].
simpl. subst; destruct t; auto; simpl in H0; inv H0; intuition.
simpl in *. subst; destruct t; intuition.
eapply typecheck_expr_sound_Evar; eauto.
eapply typecheck_lvalue_Evar; eauto.
eapply typecheck_temp_sound; eauto.
eapply typecheck_deref_sound; eauto.
intuition.
simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
destruct H0.
destruct t; auto.
eapply typecheck_unop_sound; eauto.
repeat rewrite andb_true_iff in *; intuition.
clear H4. clear H2. clear H.
simpl in H0.
repeat rewrite denote_tc_assert_andp in H0.
destruct H0 as [[H0 E1] E2].
apply (typecheck_binop_sound b Delta rho e1 e2 t H0 (H3 E2) (H1 E1)).
eapply typecheck_cast_sound; eauto.
eapply typecheck_expr_sound_Efield; eauto.
eapply typecheck_lvalue_sound_Efield; eauto.
Qed.
Lemma typecheck_expr_sound : forall Delta rho e,
typecheck_environ Delta rho ->
denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_val (eval_expr e rho) (typeof e) = true.
Proof. intros.
assert (TC := typecheck_both_sound Delta rho e). intuition. Qed.
Lemma typecheck_lvalue_sound : forall Delta rho e,
typecheck_environ Delta rho ->
denote_tc_assert (typecheck_lvalue Delta e) rho ->
(forall pt,
is_pointer_type pt = true ->
typecheck_val (eval_lvalue e rho) pt=true).
intros. edestruct (typecheck_both_sound _ _ e H).
apply H3; eauto.
Qed.
Lemma get_typed_int:
forall v att, typecheck_val v (Tint I32 Signed att) = true ->
exists i:int, v = Vint i.
intros; destruct v; inv H; eauto.
Qed.
Definition is_ptr_type (ty: type) : bool :=
match ty with
| Tpointer _ _ => true
| Tarray _ _ _ => true
| Tfunction _ _ => true
| Tstruct _ _ _ => true
| Tunion _ _ _ => true
| _ => false
end.
Lemma tc_binaryop_nomem : forall b e1 e2 m1 m2 t rho,
denote_tc_assert (isBinOpResultType b e1 e2 t) rho ->
sem_binary_operation b (eval_expr e1 rho) (typeof e1) (eval_expr e2 rho)
(typeof e2) (m1) =
sem_binary_operation b (eval_expr e1 rho) (typeof e1) (eval_expr e2 rho)
(typeof e2) (m2).
Proof.
intros.
destruct b; simpl in *; auto;
unfold sem_cmp; destruct (classify_cmp (typeof e1) (typeof e2));
try destruct i; try destruct s; auto; try contradiction;
rewrite tc_andp_sound in *; simpl in H; super_unfold_lift;
((intuition; unfold denote_tc_iszero in *));
rewrite denote_tc_assert_orp in H0; repeat rewrite denote_tc_assert_iszero in H0;
destruct H0.
* destruct (eval_expr e1 rho); try contradiction; auto.
* destruct (eval_expr e2 rho); try contradiction; auto.
* destruct (eval_expr e1 rho); try contradiction; auto.
* destruct (eval_expr e2 rho); try contradiction; auto.
Qed.
Definition some_pt_type := Tpointer Tvoid noattr.
Lemma filter_genv_zero_ofs : forall ge ge2 b i t,
filter_genv ge = ge2 ->
(forall id, ge2 id = Some (Vptr b i, t) ->
i = Int.zero).
Proof.
intros. unfold filter_genv in *. rewrite <- H in H0.
remember (Genv.find_symbol ge id). destruct o.
destruct (type_of_global ge b0); inv H0; auto.
inv H0.
Qed.
Lemma typecheck_force_Some : forall ov t, typecheck_val (force_val ov) t = true
-> exists v, ov = Some v.
Proof.
intros. destruct ov; destruct t; eauto; simpl in *; congruence.
Qed.
Lemma typecheck_binop_sound2:
forall (Delta : tycontext) (rho : environ) (b : binary_operation)
(e1 e2 : expr) (t : type),
denote_tc_assert (typecheck_expr Delta e2) rho ->
denote_tc_assert (isBinOpResultType b e1 e2 t) rho ->
denote_tc_assert (typecheck_expr Delta e1) rho ->
typecheck_val (eval_expr e2 rho) (typeof e2) = true ->
typecheck_val (eval_expr e1 rho) (typeof e1) = true ->
typecheck_val
(eval_binop b (typeof e1) (typeof e2) (eval_expr e1 rho)
(eval_expr e2 rho)) t = true.
Proof.
intros.
pose proof (typecheck_binop_sound).
simpl in H4. unfold_lift in H4. eapply H4; eauto.
Qed.
Lemma eval_binop_relate_fail :
forall (Delta : tycontext) (rho : environ) (b : binary_operation)
(e1 e2 : expr) (t : type) (m : mem),
typecheck_environ Delta rho ->
forall (ge : genv) te ve,
rho = construct_rho (filter_genv ge) ve te ->
denote_tc_assert (typecheck_expr Delta e2) rho ->
denote_tc_assert (isBinOpResultType b e1 e2 t) rho ->
denote_tc_assert (typecheck_expr Delta e1) rho ->
None =
sem_binary_operation b (eval_expr e1 rho) (typeof e1) (eval_expr e2 rho)
(typeof e2) Mem.empty ->
Clight.eval_expr ge ve te m e2 (eval_expr e2 rho) ->
Clight.eval_expr ge ve te m e1 (eval_expr e1 rho) ->
Clight.eval_expr ge ve te m (Ebinop b e1 e2 t) Vundef.
Proof.
intros.
assert (TC1 := typecheck_expr_sound _ _ _ H H1).
assert (TC2 := typecheck_expr_sound _ _ _ H H3).
copy H2.
rewrite den_isBinOpR in H7; simpl in H7.
eapply typecheck_binop_sound2 in H2; eauto.
remember (eval_expr e1 rho); remember (eval_expr e2 rho);
destruct v; destruct v0;
try solve [apply typecheck_force_Some in H2; destruct H2;
try congruence].
remember (typeof e1). remember (typeof e2).
destruct t1; try solve [inv TC1];
destruct t0; try solve [inv TC2];
destruct b; simpl in H7; try contradiction H7;
try solve[ simpl in H2; apply typecheck_force_Some in H2; destruct H2;
unfold sem_binary_operation in *; try congruence];
try rewrite tc_andp_sound in *; simpl in H7;
super_unfold_lift;
rewrite <- Heqv in *; rewrite <- Heqv0 in *;
intuition.
Qed.
Opaque tc_andp.
Equivalence of CompCert eval_expr and our function eval_expr on programs that typecheck
Lemma ptr_compare_no_binop_tc :
forall e1 e2 b1 i1 b2 i2 rho b t,
typecheck_val (eval_expr e1 rho) (typeof e1) = true ->
typecheck_val (eval_expr e2 rho) (typeof e2) = true ->
Vptr b1 i1 = eval_expr e1 rho ->
Vptr b2 i2 = eval_expr e2 rho ->
true = is_comparison b ->
~denote_tc_assert (isBinOpResultType b e1 e2 t) rho.
Proof.
intros.
unfold not. intro.
rewrite <- H1 in *. rewrite <- H2 in *.
rewrite den_isBinOpR in *.
destruct b; inv H3;
remember (typeof e1); remember (typeof e2);
destruct t1; try solve[inv H0];
destruct t0; try solve[inv H];
simpl in H4;
try rewrite tc_andp_sound in *; simpl in *; super_unfold_lift;
try rewrite <- H1 in *; try rewrite <- H2 in *; intuition.
Qed.
Lemma eval_both_relate:
forall Delta ge te ve rho e m,
rho = construct_rho (filter_genv ge) ve te ->
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_expr Delta e) rho ->
Clight.eval_expr ge ve te m e (eval_expr e rho))
/\
(denote_tc_assert (typecheck_lvalue Delta e) rho ->
exists b, exists ofs,
Clight.eval_lvalue ge ve te m e b ofs /\
eval_lvalue e rho = Vptr b ofs).
Proof.
intros. generalize dependent ge. induction e; intros;
try solve[intuition; constructor; auto | subst; inv H1]; intuition.
assert (TC_Sound:= typecheck_expr_sound).
specialize (TC_Sound Delta rho (Evar i t) H0 H1).
simpl in TC_Sound|-*.
super_unfold_lift.
unfold deref_noload in TC_Sound|-*.
revert TC_Sound; case_eq (access_mode t); intros; try solve [inv TC_Sound].
rename H2 into MODE.
simpl in *. rewrite MODE in H1.
unfold get_var_type, eval_var in *.
remember (Map.get (ve_of rho) i); destruct o; try destruct p;
try rewrite eqb_type_eq in *; simpl in *.
destruct (type_eq t t0); simpl in *; intuition.
subst t0. if_tac; intuition.
apply Clight.eval_Elvalue with b Int.zero;
[ | constructor; simpl; rewrite MODE; auto].
apply eval_Evar_local.
subst rho.
simpl in Heqo. symmetry in Heqo; apply Heqo.
subst rho.
unfold typecheck_environ in *.
destruct H0 as [? [Hve [Hge _]]].
hnf in Hve,Hge.
revert H1; case_eq ((var_types Delta) ! i); intros; try contradiction.
destruct (Hve _ _ H0). simpl in *; congruence.
revert H1; case_eq ((glob_types Delta) ! i); intros; try contradiction.
destruct (Hge _ _ H1) as [b [ofs [? ?]]].
simpl. simpl in H3.
rewrite H3.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
destruct H2. unfold tc_bool in H2.
if_tac in H2; try contradiction.
apply Clight.eval_Elvalue with b ofs; [ | econstructor 2; apply MODE].
assert (ZO := filter_genv_zero_ofs _ _ _ _ _ (eq_refl _) _ H3). subst.
apply Clight.eval_Evar_global.
symmetry in Heqo; apply Heqo.
unfold filter_genv in *. invSome. destruct (type_of_global ge b0); inv H8; auto.
unfold filter_genv in *.
remember (Genv.find_symbol ge i).
destruct o; try congruence.
assert (b = b0). clear - Heqo0 H3. rename H3 into H4.
destruct (type_of_global ge b0); inv H4; auto.
subst.
remember (type_of_global ge b0).
destruct o; try congruence. inv H3.
remember (eqb_type t (globtype g)). destruct b.
symmetry in Heqb. apply eqb_type_true in Heqb. auto.
destruct t; inv TC_Sound. inv H3. rewrite <- H7 in H4; inv H4.
assert (TC_Sound:= typecheck_lvalue_sound).
specialize (TC_Sound Delta rho (Evar i t) H0 H1).
specialize (TC_Sound some_pt_type). simpl in TC_Sound.
specialize (TC_Sound (eq_refl _)).
simpl in *. unfold eval_var in *.
remember (Map.get (ve_of rho) i); destruct o; try destruct p;
try rewrite eqb_type_eq in *; simpl in *.
destruct (type_eq t t0); simpl in *; intuition.
subst t0. if_tac; intuition.
exists b. exists Int.zero. intuition. constructor.
unfold Map.get in Heqo. unfold construct_rho in *.
destruct rho; inv H; simpl in *; auto.
remember (ge_of rho i). destruct o; try destruct p; auto;
try rewrite eqb_type_eq in *; simpl in *; intuition.
destruct (type_eq t t0); simpl in *. subst t0.
unfold get_var_type in *.
remember ((var_types Delta) ! i).
destruct o; try rewrite eqb_type_eq in *; simpl in *; super_unfold_lift; intuition.
destruct (type_eq t t0); simpl in *; [ | contradiction]. subst t0.
symmetry in Heqo1.
destruct rho.
unfold typecheck_environ in *.
intuition. clear H2 H5.
unfold typecheck_var_environ, typecheck_glob_environ in *.
specialize (H0 i t Heqo1). unfold ge_of in *. unfold Map.get in *.
destruct H0. congruence.
destruct rho.
unfold typecheck_environ in *; intuition. clear H2 H0 H5.
unfold typecheck_glob_environ in *.
remember ((glob_types Delta) ! i). destruct o; simpl in H1; try congruence.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift. destruct H1.
rename H3 into H4.
symmetry in Heqo2. specialize (H4 _ _ Heqo2). destruct H4. destruct H2.
destruct H2. simpl in Heqo0. rewrite H2 in *. inv Heqo0. exists x. exists x0. split; auto.
unfold construct_rho in *. inv H. simpl in Heqo. clear H1.
remember (filter_genv ge). symmetry in Heqg0.
assert (ZO := filter_genv_zero_ofs _ _ _ _ _ Heqg0 _ H2). subst.
apply Clight.eval_Evar_global. auto. unfold filter_genv in H2.
destruct (Genv.find_symbol ge i). destruct (type_of_global ge b); inv H2; auto.
congruence.
unfold filter_genv in H2.
remember (Genv.find_symbol ge i). destruct o; try congruence.
assert (x = b). destruct (type_of_global ge b); inv H2; auto. subst.
destruct (type_of_global ge b). inv H2; auto. inv H2. rewrite <- H1 in *. simpl in *.
congruence.
intuition. congruence.
assert (TC:= typecheck_expr_sound).
specialize (TC Delta rho (Etempvar i t)). simpl in *.
intuition.
constructor. unfold eval_id in *. remember (Map.get (te_of rho) i);
destruct o; auto. destruct rho; inv H; unfold make_tenv in *.
unfold Map.get in *. auto.
simpl in *. congruence.
assert (TC:= typecheck_lvalue_sound _ _ _ H0 H1).
specialize (IHe ge). intuition. simpl in H1.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
intuition. simpl. super_unfold_lift; unfold_tc_denote.
remember (eval_expr e rho); destruct v;
intuition.
exists b. exists i. simpl in *. intuition. constructor.
auto.
simpl in H1.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift.
assert (ISPTR := eval_lvalue_ptr rho e Delta (te_of rho) (ve_of rho) (ge_of rho)).
specialize (IHe ge).
assert (mkEnviron (ge_of rho) (ve_of rho) (te_of rho) = rho). destruct rho; auto.
destruct rho. unfold typecheck_environ in *. intuition.
simpl. destruct H10. destruct H9. intuition. congruence.
destruct H10. destruct H9. destruct H6. destruct H6. destruct H9. simpl in *.
intuition. rewrite H6 in *. constructor. inv H10. auto.
simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
unfold eval_unop in *. super_unfold_lift. intuition. unfold force_val.
remember (sem_unary_operation u (eval_expr e rho) (typeof e)).
destruct o. eapply Clight.eval_Eunop. eapply IHe; eauto. rewrite Heqo. auto.
apply typecheck_expr_sound in H3; auto. unfold sem_unary_operation in *.
destruct u. simpl in *. remember (typeof e); destruct t0; try inv H2;
try destruct i;try destruct s; try inv H2; simpl in *; destruct t; intuition;
destruct (eval_expr e rho); intuition; unfold sem_notbool in *;
simpl in *; inv Heqo.
simpl in *. remember (typeof e). destruct t0;
try destruct i; try destruct s; try inversion H3; simpl in *; destruct t; intuition;
destruct (eval_expr e rho); intuition; unfold sem_notint in *;
simpl in *; inv Heqo.
simpl in *. remember (typeof e). destruct t0;
try destruct i; try destruct s; try inversion H3; simpl in *; destruct t; intuition;
destruct (eval_expr e rho); intuition; unfold sem_neg in *;
simpl in *; inv Heqo.
simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
unfold eval_binop in *; super_unfold_lift; intuition. unfold force_val.
remember (sem_binary_operation b (eval_expr e1 rho) (typeof e1) (eval_expr e2 rho)
(typeof e2) Mem.empty).
{ destruct o.
+ eapply Clight.eval_Ebinop. eapply IHe1; eauto.
eapply IHe2. apply H. apply H3.
remember (eval_expr e1 rho); remember (eval_expr e2 rho);
destruct v0; destruct v1; simpl;
rewrite Heqv0 at 1; rewrite Heqv1;
rewrite Heqv0 in Heqo at 1;
rewrite Heqv1 in Heqo;
try rewrite Heqo;
try apply tc_binaryop_nomem with (t:=t); auto.
remember (is_comparison b). destruct b2.
- apply typecheck_expr_sound in H3; auto.
apply typecheck_expr_sound in H4; auto.
eapply ptr_compare_no_binop_tc in H1; eauto;
try contradiction.
- rewrite Heqo.
remember (eval_expr e1 rho). remember (eval_expr e2 rho).
destruct v; destruct v0;
try solve [try
rewrite Heqv in *; try rewrite Heqv0 in *; eauto];
rewrite Heqv2; rewrite Heqv3;
eapply tc_binaryop_nomem; eauto.
+ specialize (IHe1 ge). specialize (IHe2 ge). intuition.
clear H6 H8.
remember (eval_expr e1 rho). remember (eval_expr e2 rho).
destruct v; destruct v0;
rewrite Heqv in Heqo at 1, H7;
rewrite Heqv0 in Heqo, H2;
try eapply eval_binop_relate_fail; eauto.
remember (is_comparison b). destruct b2.
apply typecheck_expr_sound in H3; auto.
apply typecheck_expr_sound in H4; auto.
eapply ptr_compare_no_binop_tc in H1; eauto;
try contradiction.
try eapply eval_binop_relate_fail; eauto. }
{
assert (TC := typecheck_expr_sound _ _ _ H0 H1).
simpl in *;
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
unfold eval_cast in *; super_unfold_lift; intuition.
eapply Clight.eval_Ecast.
eapply IHe; auto.
unfold sem_cast.
remember (classify_cast (typeof e) t) as o; destruct o;
destruct (eval_expr e rho); inv TC; try reflexivity;
try solve [destruct (ident_eq id1 id2); inv H4; destruct (fieldlist_eq fld1 fld2); inv H1;
(reflexivity || destruct t; inv H4; destruct (typeof e); try destruct i0; inv Heqo)].
simpl; destruct (cast_float_int si2 f); inv H4; reflexivity.
simpl; destruct (cast_float_long si2 f); inv H4; reflexivity.
simpl; destruct (ident_eq id1 id2 && fieldlist_eq fld1 fld2); inv H4; reflexivity.
simpl; destruct (ident_eq id1 id2 && fieldlist_eq fld1 fld2); inv H4; reflexivity.
}
specialize (IHe ge H). assert (TC := typecheck_expr_sound _ _ _ H0 H1).
simpl in H1. remember (access_mode t). destruct m0; try solve [inv H1]. repeat rewrite tc_andp_sound in *.
simpl in H1.
repeat( try rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
destruct H1. destruct H1.
destruct IHe. specialize (H5 H1). destruct H5 as [b [ofs H5]].
destruct H5.
remember (typeof e).
destruct t0; try solve[inv H3]. remember (field_offset i f). destruct r; inv H3. simpl in *. rewrite <- Heqr in *.
unfold deref_noload in *. rewrite <- Heqm0 in *.
eapply Clight.eval_Elvalue; eauto.
eapply Clight.eval_Efield_struct; eauto.
eapply Clight.eval_Elvalue; auto. apply H5.
rewrite <- Heqt0.
apply Clight.deref_loc_copy. auto. simpl.
rewrite H6. apply Clight.deref_loc_reference. auto.
unfold deref_noload. rewrite <- Heqm0. simpl.
eapply Clight.eval_Elvalue; eauto.
eapply Clight.eval_Efield_union.
eapply Clight.eval_Elvalue; eauto.
apply Clight.deref_loc_copy.
rewrite <- Heqt0. auto. eauto.
simpl. rewrite H6. simpl. apply Clight.deref_loc_reference; auto.
assert (TC:= typecheck_lvalue_sound _ _ _ H0 H1).
specialize (IHe ge). specialize (TC some_pt_type). intuition. simpl in H1.
simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
unfold eval_field,offset_val in *; super_unfold_lift; remember (eval_lvalue e rho).
destruct H1. destruct H1. specialize (H4 H1).
destruct H4 as [b [ofs H4]].
remember (typeof e) as t0. destruct t0; intuition.
remember (field_offset i f) as r.
destruct r; intuition.
destruct v; intuition. simpl in *. exists b. exists (Int.add ofs (Int.repr z)).
intuition. inv H8.
eapply Clight.eval_Efield_struct; auto.
eapply Clight.eval_Elvalue in H7. apply H7.
rewrite <- Heqt0. auto. apply Clight.deref_loc_copy. simpl; auto.
rewrite <- Heqt0; reflexivity. auto.
inv H8; auto.
subst v.
exists b, ofs. rewrite H8. simpl. split; auto.
eapply Clight.eval_Efield_union; eauto.
eapply Clight.eval_Elvalue; eauto.
rewrite <- Heqt0. apply Clight.deref_loc_copy.
auto.
Qed.
Lemma eval_expr_relate:
forall Delta ge te ve rho e m,
rho = construct_rho (filter_genv ge) ve te ->
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_expr Delta e) rho ->
Clight.eval_expr ge ve te m e (eval_expr e rho)).
Proof.
intros.
edestruct eval_both_relate; eauto.
Qed.
Lemma eval_lvalue_relate:
forall Delta ge te ve rho e m,
rho = construct_rho (filter_genv ge) ve te->
typecheck_environ Delta rho ->
(denote_tc_assert (typecheck_lvalue Delta e) rho ->
exists b, exists ofs,
Clight.eval_lvalue ge ve te m e b ofs /\
eval_lvalue e rho = Vptr b ofs).
apply eval_both_relate.
Qed.
Lemma tc_lvalue_nonvol : forall rho Delta e,
(denote_tc_assert (typecheck_lvalue Delta e) rho) ->
type_is_volatile (typeof e) = false.
Proof.
intros.
destruct e; intuition; simpl in *.
unfold get_var_type in *.
destruct ((var_types Delta) ! i); intuition; simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift;
intuition. unfold tc_bool in *. rewrite if_negb in *.
if_tac in H1; simpl in *; super_unfold_lift; intuition.
super_unfold_lift; intuition. unfold tc_bool in *. rewrite if_negb in *.
destruct ((glob_types Delta) ! i). simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift.
destruct H. if_tac in H0; auto; inv H0. inv H.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift; intuition. clear - H1. unfold tc_bool in *. rewrite if_negb in *.
if_tac in H1; intuition.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift. intuition. unfold tc_bool in *. rewrite if_negb in *.
if_tac in H1; auto. inv H1.
Qed.
Lemma join_te_eqv :forall te1 te2 id b1 b2 t1,
te1 ! id = Some (t1, b1) -> te2 ! id = Some (t1, b2) ->
(join_te te1 te2) ! id = Some (t1,andb b1 b2).
Proof.
intros.
unfold join_te. rewrite PTree.fold_spec. rewrite <- fold_left_rev_right.
assert (forall t : type * bool, In (id, t) (rev (PTree.elements te1)) -> te1 ! id = Some t).
intros. apply PTree.elements_complete. apply in_rev. auto.
assert (forall t, te1 ! id = Some t -> In (id, t) (rev (PTree.elements te1))).
intros. apply In_rev. rewrite rev_involutive. apply PTree.elements_correct.
auto.
induction (rev (PTree.elements te1)). simpl in *.
apply H2 in H. inv H.
simpl in *. destruct a. simpl in *. destruct p0. simpl.
remember (te2 ! p). destruct o. destruct p0.
rewrite PTree.gsspec. if_tac. subst. specialize (H1 (t,b)).
spec H1; [solve [auto] | ].
inversion2 H H1.
rewrite H0 in Heqo; inv Heqo. auto.
apply IHl; auto.
intros. inversion2 H H4. specialize (H2 _ H).
destruct H2. inv H2. congruence. auto.
apply IHl; auto; intros. rewrite H in *. inv H3. specialize (H2 (t1, b1)).
intuition. inv H2. congruence.
Qed.
Lemma temp_types_same_type : forall id i t b Delta,
(temp_types Delta) ! id = Some (t, b) ->
exists b0 : bool,
(temp_types (initialized i Delta)) ! id = Some (t, b || b0).
Proof.
intros.
unfold initialized.
remember ((temp_types Delta) ! i). destruct o.
destruct p. unfold temp_types in *. simpl. rewrite PTree.gsspec.
if_tac. subst. rewrite H in *. inv Heqo. exists true. rewrite orb_true_r.
eauto. exists false. rewrite orb_false_r. eauto. exists false. rewrite orb_false_r.
auto.
Qed.
Lemma temp_types_update_dist : forall d1 d2 ,
(temp_types (join_tycon (d1) (d2))) =
join_te (temp_types (d1)) (temp_types (d2)).
Proof.
intros.
destruct d1; destruct d2. destruct p; destruct p0. destruct p0; destruct p.
simpl. unfold temp_types. simpl. auto.
Qed.
Lemma var_types_update_dist : forall d1 d2 ,
(var_types (join_tycon (d1) (d2))) =
(var_types (d1)).
Proof.
intros.
destruct d1; destruct d2. destruct p; destruct p0. destruct p0; destruct p.
simpl. unfold var_types. simpl. auto.
Qed.
Lemma ret_type_update_dist : forall d1 d2,
(ret_type (join_tycon (d1) (d2))) =
(ret_type (d1)).
Proof.
intros.
destruct d1; destruct d2. destruct p; destruct p0. destruct p0; destruct p.
simpl. unfold var_types. simpl. auto.
Qed.
Lemma glob_types_update_dist :
forall d1 d2,
(glob_types (join_tycon (d1) (d2))) =
(glob_types (d1)).
Proof.
intros. destruct d1. destruct d2. destruct p. destruct p0.
destruct p. destruct p0. simpl. auto.
Qed.
Lemma var_types_update_tycon:
forall c Delta, var_types (update_tycon Delta c) = var_types Delta
with
var_types_join_labeled : forall l Delta,
var_types (join_tycon_labeled l Delta) = var_types Delta.
Proof.
assert (forall i Delta, var_types (initialized i Delta) = var_types Delta).
intros; unfold initialized.
destruct ((temp_types Delta)!i); try destruct p; reflexivity.
destruct c; intros; simpl; try reflexivity.
apply H.
destruct o. apply H. auto.
rewrite var_types_update_tycon. apply var_types_update_tycon.
rewrite var_types_update_dist. apply var_types_update_tycon.
apply var_types_join_labeled.
intros. destruct l. simpl. apply var_types_update_tycon.
simpl. rewrite var_types_update_dist.
rewrite var_types_update_tycon. reflexivity.
Qed.
Lemma glob_types_update_tycon:
forall c Delta, glob_types (update_tycon Delta c) = glob_types Delta
with
glob_types_join_labeled : forall Delta e l,
glob_types (update_tycon Delta (Sswitch e l)) = glob_types Delta.
Proof.
clear glob_types_update_tycon.
assert (forall i Delta, glob_types (initialized i Delta) = glob_types Delta).
intros; unfold initialized.
destruct ((temp_types Delta)!i); try destruct p; reflexivity.
induction c; intros; try apply H; try reflexivity.
simpl. destruct o. apply H. auto.
simpl.
rewrite IHc2.
auto.
simpl. rewrite glob_types_update_dist. auto.
auto.
clear glob_types_join_labeled.
intros. simpl.
destruct l. simpl. auto.
simpl in *. rewrite glob_types_update_dist.
auto.
Qed.
Ltac try_false :=
try solve[exists false; rewrite orb_false_r; eauto].
Lemma update_tycon_te_same : forall c Delta id t b,
(temp_types Delta) ! id = Some (t,b) ->
exists b2, (temp_types (update_tycon Delta c)) ! id = Some (t,b || b2)
with update_labeled_te_same : forall ls Delta id t b,
(temp_types Delta) ! id = Some (t,b) ->
exists b2, (temp_types (join_tycon_labeled ls Delta)) ! id = Some (t,b || b2) .
Focus 1.
destruct c; intros; simpl; try_false.
simpl. eapply temp_types_same_type; eauto.
simpl. destruct o; eauto. simpl. eapply temp_types_same_type; eauto.
try_false; eauto.
assert (forall (c : statement) (Delta : tycontext)
(id : positive) (t : type) (b : bool),
(temp_types Delta) ! id = Some (t, b) ->
exists b2 : bool,
(temp_types (update_tycon Delta c)) ! id =
Some (t, b || b2)) by auto.
edestruct update_tycon_te_same. apply H.
specialize (update_tycon_te_same c2 _ _ _ _ H1).
destruct (update_tycon_te_same). exists (x || x0). rewrite orb_assoc. eauto.
simpl. rewrite temp_types_update_dist.
edestruct (update_tycon_te_same c1). apply H.
edestruct (update_tycon_te_same c2). apply H.
erewrite join_te_eqv;
eauto. exists (x && x0). rewrite orb_andb_distrib_r. auto.
apply update_labeled_te_same. exact H.
intros. destruct ls. simpl. eauto.
simpl. rewrite temp_types_update_dist.
edestruct update_tycon_te_same. apply H.
edestruct update_labeled_te_same. apply H.
exists (x && x0).
erewrite join_te_eqv. rewrite <- orb_andb_distrib_r. auto.
eauto. eauto. Qed.
Lemma typecheck_environ_update_te:
forall rho c Delta, typecheck_temp_environ (te_of rho) (temp_types (update_tycon Delta c))
->
typecheck_temp_environ (te_of rho) (temp_types Delta)
with typecheck_ls_update_te : forall Delta ty b id l,
(temp_types Delta) ! id = Some (ty, b) ->
exists b2, (temp_types (join_tycon_labeled l Delta)) ! id = Some (ty, b2).
Proof.
intros.
unfold typecheck_temp_environ in H. unfold typecheck_temp_environ.
destruct c; intros; simpl in *; try solve[eapply H; apply H0].
destruct (eq_dec id i). subst.
destruct (H i true ty). unfold initialized. rewrite H0.
unfold temp_types. simpl. rewrite PTree.gsspec. rewrite peq_true.
auto. destruct H1. destruct H2. inv H2. exists x. auto.
apply H.
unfold initialized.
remember ((temp_types Delta) ! i). destruct o. destruct p.
unfold temp_types. simpl. rewrite PTree.gsspec.
rewrite peq_false by auto. apply H0. auto.
destruct o.
destruct (eq_dec id i). subst. destruct (H i true ty).
unfold initialized.
remember ((temp_types Delta) ! i). destruct o. destruct p.
unfold temp_types. simpl. inv H0.
rewrite PTree.gsspec. rewrite peq_true. eauto. congruence.
destruct H1. destruct H2. inv H2. eauto.
eapply H. unfold initialized.
remember ((temp_types Delta) ! i). destruct o. destruct p.
unfold temp_types. simpl. rewrite PTree.gsspec.
rewrite peq_false by auto. apply H0. auto. eauto.
destruct (update_tycon_te_same c1 _ _ _ _ H0).
destruct (update_tycon_te_same c2 _ _ _ _ H1).
edestruct H. apply H2. destruct H3. exists x1.
split. apply H3. destruct b. auto. auto.
destruct (update_tycon_te_same c1 _ _ _ _ H0).
destruct (update_tycon_te_same c2 _ _ _ _ H0).
specialize (H id ((b || x) && (b || x0)) ty ).
spec H.
unfold join_tycon. remember (update_tycon Delta c1).
destruct t. destruct p. destruct p. remember (update_tycon Delta c2).
destruct t3. destruct p. destruct p. unfold temp_types in *.
unfold update_tycon. simpl in *.
apply join_te_eqv; eauto. destruct b; auto. simpl in *.
destruct H. exists x1. split. destruct H. auto. left. auto.
edestruct (update_labeled_te_same l Delta id). apply H0.
edestruct H. apply H1.
destruct H2. exists x0. destruct b; auto.
intros. destruct l; simpl in *.
destruct (update_tycon_te_same s _ _ _ _ H).
eauto.
destruct (update_tycon_te_same s _ _ _ _ H).
edestruct typecheck_ls_update_te. apply H.
rewrite temp_types_update_dist. erewrite join_te_eqv; eauto.
Qed.
Lemma set_temp_ve : forall Delta i,
var_types (initialized i Delta) = var_types (Delta).
Proof.
intros. destruct Delta. destruct p. destruct p. unfold var_types. unfold initialized.
simpl. unfold temp_types. simpl. destruct (t1 ! i); auto. destruct p; auto.
Qed.
Lemma set_temp_ge : forall Delta i,
glob_types (initialized i Delta) = glob_types (Delta).
Proof.
intros. destruct Delta. destruct p. destruct p. unfold var_types. unfold initialized.
simpl. unfold temp_types. simpl. destruct (t1 ! i); auto. destruct p; auto.
Qed.
Lemma set_temp_ret : forall Delta i,
ret_type (initialized i Delta) = ret_type (Delta).
intros.
destruct Delta. destruct p. destruct p. unfold var_types. unfold initialized.
simpl. unfold temp_types. simpl. destruct (t1 ! i); auto. destruct p; auto.
Qed.
Lemma update_tycon_eqv_ve : forall Delta c id,
(var_types (update_tycon Delta c)) ! id = (var_types (Delta)) ! id
with update_le_eqv_ve : forall (l : labeled_statements) (id : positive) Delta,
(var_types (join_tycon_labeled l Delta)) ! id =
(var_types Delta) ! id.
Proof.
intros;
destruct c; simpl in *; try reflexivity.
rewrite set_temp_ve. auto.
destruct o. rewrite set_temp_ve. auto.
auto.
rewrite update_tycon_eqv_ve. apply update_tycon_eqv_ve.
rewrite var_types_update_dist.
rewrite update_tycon_eqv_ve. auto.
erewrite update_le_eqv_ve. auto.
intros.
destruct l. simpl in *. rewrite update_tycon_eqv_ve.
reflexivity.
simpl in *. rewrite var_types_update_dist.
rewrite update_tycon_eqv_ve. auto.
Qed.
Lemma update_tycon_eqv_ret : forall Delta c,
(ret_type (update_tycon Delta c)) = (ret_type (Delta))
with update_le_eqv_ret : forall (l : labeled_statements) Delta,
(ret_type (join_tycon_labeled l Delta)) =
(ret_type Delta).
Proof.
intros;
destruct c; simpl in *; try reflexivity.
rewrite set_temp_ret. auto.
destruct o. rewrite set_temp_ret. auto.
auto.
rewrite update_tycon_eqv_ret. apply update_tycon_eqv_ret.
rewrite ret_type_update_dist.
rewrite update_tycon_eqv_ret. auto.
rewrite update_le_eqv_ret. auto.
intros.
destruct l. simpl in *. rewrite update_tycon_eqv_ret.
reflexivity.
simpl in *. rewrite ret_type_update_dist.
rewrite update_tycon_eqv_ret. auto.
Qed.
Lemma update_tycon_same_ve : forall Delta c id v,
(var_types (update_tycon Delta c)) ! id = Some v <->
(var_types (Delta)) ! id = Some v
with update_le_same_ve : forall (l : labeled_statements) (id : positive) (v : type) Delta,
(var_types (join_tycon_labeled l Delta)) ! id = Some v <->
(var_types Delta) ! id = Some v.
Proof.
intros; split; intros;
rewrite update_tycon_eqv_ve in *; auto.
intros; split; intros;
rewrite update_le_eqv_ve in *; auto.
Qed.
Lemma update_tycon_eqv_ge : forall Delta c id,
(glob_types (update_tycon Delta c)) ! id = (glob_types (Delta)) ! id
with update_le_eqv_ge : forall (l : labeled_statements) (id : positive) Delta,
(glob_types (join_tycon_labeled l Delta)) ! id =
(glob_types Delta) ! id.
Proof.
intros;
destruct c; simpl in *; try reflexivity.
rewrite set_temp_ge. auto.
destruct o. rewrite set_temp_ge. auto.
auto.
rewrite update_tycon_eqv_ge. apply update_tycon_eqv_ge.
rewrite glob_types_update_dist.
rewrite update_tycon_eqv_ge. auto.
erewrite update_le_eqv_ge. auto.
intros.
destruct l. simpl in *. rewrite update_tycon_eqv_ge.
auto.
simpl in *. rewrite glob_types_update_dist.
rewrite update_tycon_eqv_ge. auto.
Qed.
Lemma update_tycon_same_ge : forall Delta c id v,
(glob_types (update_tycon Delta c)) ! id = Some v <->
(glob_types (Delta)) ! id = Some v
with update_le_same_ge : forall (l : labeled_statements) (id : positive) (v : global_spec) Delta,
(glob_types (join_tycon_labeled l Delta)) ! id = Some v <->
(glob_types Delta) ! id = Some v.
Proof.
intros; split; intros;
rewrite update_tycon_eqv_ge in *; auto.
intros; split; intros;
rewrite update_le_eqv_ge in *; auto.
Qed.
Lemma typecheck_environ_update_ve : forall (rho : environ) (c : statement) (Delta : tycontext),
typecheck_var_environ (ve_of rho) (var_types (update_tycon Delta c)) ->
typecheck_var_environ (ve_of rho) (var_types Delta).
Proof.
intros.
destruct c; simpl in *; try apply H;
try destruct o; try rewrite set_temp_ve in *; try apply H;
unfold typecheck_var_environ in *; intros; apply H; try rewrite var_types_update_dist;
try apply join_ve_eqv;
repeat rewrite update_tycon_same_ve in *; try rewrite update_le_same_ve;
auto.
Qed.
Lemma typecheck_environ_update_ge : forall (rho : environ) (c : statement) (Delta : tycontext),
typecheck_glob_environ (ge_of rho) (glob_types (update_tycon Delta c)) ->
typecheck_glob_environ (ge_of rho) (glob_types Delta).
Proof.
intros. destruct c; simpl in *; try apply H;
try destruct o; try rewrite set_temp_ge in *; try apply H;
unfold typecheck_glob_environ in *; intros; apply H; try rewrite glob_types_update_dist;
try apply join_ge_eqv;
repeat rewrite update_tycon_same_ge in *; try rewrite update_le_same_ge;
auto.
Qed.
Lemma typecheck_environ_update:
forall rho c Delta, typecheck_environ (update_tycon Delta c) rho ->
typecheck_environ Delta rho.
Proof.
intros. unfold typecheck_environ in *. intuition.
clear H H1 H3. unfold typecheck_temp_environ in *.
eapply typecheck_environ_update_te; eauto.
clear -H. eapply typecheck_environ_update_ve; eauto.
eapply typecheck_environ_update_ge.
eauto.
clear - H3.
unfold same_env in *. intros.
specialize (H3 id t).
repeat rewrite update_tycon_same_ge in *. specialize (H3 H).
destruct H3; auto. destruct H0.
rewrite update_tycon_same_ve in *. eauto.
Qed.
Lemma typecheck_bool_val:
forall v t, typecheck_val v t = true -> bool_type t = true ->
exists b, strict_bool_val v t = Some b.
Proof.
intros.
destruct t; inv H0;
destruct v; inv H; simpl; try rewrite H1; eauto.
Qed.
Lemma map_ptree_rel : forall id v te, Map.set id v (make_tenv te) = make_tenv (PTree.set id v te).
intros. unfold Map.set. unfold make_tenv. extensionality. rewrite PTree.gsspec; auto.
Qed.
Lemma cast_exists : forall Delta e2 t rho
(TC: typecheck_environ Delta rho),
denote_tc_assert (typecheck_expr Delta e2) rho ->
denote_tc_assert (isCastResultType (typeof e2) t t e2)
rho ->
sem_cast (eval_expr e2 rho) (typeof e2) t =
Some (force_val (sem_cast (eval_expr e2 rho) (typeof e2) t)).
Proof.
intros.
assert (exists v, sem_cast (eval_expr e2 rho) (typeof e2) t= Some v).
apply typecheck_expr_sound in H.
rename t into t0.
remember (typeof e2); remember (eval_expr e2 rho).
unfold sem_cast. unfold classify_cast.
Transparent Float.intoffloat.
Transparent Float.intuoffloat.
Transparent liftx.
destruct t; destruct v; destruct t0; simpl in *;
try congruence; try contradiction; eauto;
try solve [
unfold Float.intoffloat, Float.intuoffloat; repeat invSome;
inversion2 H1 H0; hnf in H2,H3; rewrite H3; rewrite Zle_bool_rev; rewrite H2;
simpl; eauto];
try solve [
try destruct i; try destruct s; try destruct i0; try destruct i1; try destruct s0; eauto |
destruct i; destruct s; super_unfold_lift; try solve[simpl in *;
super_unfold_lift; unfold_tc_denote; destruct H0;
try rewrite <- Heqv in *;
unfold Float.intoffloat;
destruct (Float.Zoffloat f0); try contradiction;
try rewrite H0; try rewrite H1; simpl; eauto |
simpl in *; unfold Float.intuoffloat; destruct H0;
unfold_tc_denote; try rewrite <- Heqv in *; destruct (Float.Zoffloat f0);
try rewrite H0; try rewrite H1; simpl; eauto; try contradiction] |
try destruct i0; try destruct i1; destruct s; simpl in *; try contradiction; try rewrite H; eauto ].
destruct i; destruct s; super_unfold_lift;
simpl in *; super_unfold_lift;
unfold Float.intoffloat, Float.intuoffloat;
try (
destruct H0 as [H0 H1]; hnf in H0,H1; rewrite <- Heqv in *;
destruct (Float.Zoffloat f0); try contradiction;
hnf in H0,H1; rewrite H0; rewrite Zle_bool_rev; rewrite H1;
simpl; eauto);
simpl; eauto.
auto.
Opaque Float.intoffloat.
Opaque Float.intuoffloat.
Opaque liftx.
destruct H1. rewrite H1. auto.
Qed.
Lemma eval_cast_sem_cast:
forall v t t', eval_cast t t' v = force_val (sem_cast v t t').
Proof.
unfold sem_cast, eval_cast, classify_cast.
intros.
pose (tx:=t); pose (t'x := t'); pose (v' := v).
destruct t,t'; simpl; try reflexivity;
try solve [destruct v; reflexivity];
try solve[ destruct i; try reflexivity; try solve [destruct v; reflexivity]];
try solve[ destruct i0; try reflexivity]; simpl.
destruct i0, s0, v; reflexivity.
destruct i,v; simpl; try reflexivity; destruct (cast_float_int s f0); reflexivity.
unfold eval_cast_f2f.
destruct v; try reflexivity.
simpl. destruct (cast_float_long s f0); reflexivity.
destruct v; simpl; try reflexivity.
destruct (ident_eq i i0 && fieldlist_eq f f0); reflexivity.
destruct v; simpl; try reflexivity.
destruct (ident_eq i i0 && fieldlist_eq f f0); reflexivity.
destruct i0, v; reflexivity.
Qed.
Lemma sem_cast_eval_cast:
forall v1 t1 t2 v,
sem_cast v1 t1 t2 = Some v -> eval_cast t1 t2 v1 = v.
Proof.
intros.
rewrite eval_cast_sem_cast.
rewrite H; reflexivity.
Qed.
Lemma typecheck_val_eval_cast:
forall t2 e2 rho Delta,
typecheck_environ Delta rho ->
denote_tc_assert (typecheck_expr Delta e2) rho ->
denote_tc_assert (isCastResultType (typeof e2) t2 t2 e2) rho ->
typecheck_val (eval_cast (typeof e2) t2 (eval_expr e2 rho)) t2 = true.
Proof. intros ? ? ? ? H2 H5 H6.
assert (H7 := cast_exists _ _ _ _ H2 H5 H6).
assert (H8 := typecheck_expr_sound _ _ _ H2 H5).
clear - H7 H6 H8.
rewrite eval_cast_sem_cast.
revert H7; case_eq (sem_cast (eval_expr e2 rho) (typeof e2) t2); intros; inv H7.
simpl.
rewrite isCastR in H6.
case_eq (eval_expr e2 rho); intros; rename H0 into H99;
destruct t2; inv H8; inv H; simpl; auto;
hnf in H6; try contradiction; rewrite H99 in *;
destruct (typeof e2); inv H2; inv H1; auto;
try (unfold sem_cast in H0; simpl in H0;
destruct i0; simpl in*; destruct s; inv H0; simpl; auto);
try solve [super_unfold_lift; unfold denote_tc_iszero in H6; rewrite H99 in *; contradiction].
simpl in *. super_unfold_lift. rewrite H99 in *. inv H6. auto.
simpl in *. super_unfold_lift. rewrite H99 in *. inv H6. auto.
simpl in *. unfold isCastResultType in H6. simpl in H6.
unfold sem_cast in H0. simpl in H0.
destruct i; simpl in*; destruct s; try destruct f; inv H0; simpl; auto;
invSome; simpl; auto.
Qed.
Definition func_tycontext_t_denote :=
forall p t id ty b, list_norepet (map fst p ++ map fst t ) ->
((make_tycontext_t p t) ! id = Some (ty,b) <-> (In (id,ty) p /\ b=true) \/ (In (id,ty) t /\ b=false)).
Definition func_tycontext_v_denote :=
forall v id ty, list_norepet (map fst v) ->
((make_tycontext_v v) ! id = Some ty <-> In (id,ty) v).
Lemma func_tycontext_v_sound : func_tycontext_v_denote.
unfold func_tycontext_v_denote. intros.
split; intros; induction v. simpl in *.
rewrite PTree.gempty in *. congruence.
simpl in *. destruct a. inv H. rewrite PTree.gsspec in *. if_tac in H0.
inv H0. auto. intuition.
inv H0.
simpl in *. destruct a. simpl in *. rewrite PTree.gsspec. destruct H0.
inv H0. if_tac. auto. intuition. inv H. if_tac. subst.
clear - H0 H3. rewrite in_map_iff in *. destruct H3. exists (i,ty). auto.
apply IHv; auto.
Qed.
Lemma set_inside : forall i0 t1 t p id,
list_disjoint (map fst p) (i0 :: map fst t) ->
(fold_right
(fun param : ident * type =>
PTree.set (fst param) (snd param, true))
(PTree.set i0 (t1, false)
(fold_right
(fun (temp : ident * type) (tenv : PTree.t (type * bool)) =>
let (id, ty) := temp in PTree.set id (ty, false) tenv)
(PTree.empty (type * bool)) t)) p) ! id =
(PTree.set i0 (t1, false) (
(fold_right
(fun param : ident * type =>
PTree.set (fst param) (snd param, true))
(fold_right
(fun (temp : ident * type) (tenv : PTree.t (type * bool)) =>
let (id, ty) := temp in PTree.set id (ty, false) tenv)
(PTree.empty (type * bool)) t)) p)) ! id
.
Proof.
intros.
induction t.
simpl in *. rewrite PTree.gsspec.
if_tac.
subst.
induction p.
simpl in *. rewrite PTree.gsspec. rewrite peq_true. auto.
simpl in *. rewrite PTree.gsspec. if_tac. subst.
clear - H. unfold list_disjoint in *. specialize (H (fst a) (fst a)).
intuition. apply IHp. unfold list_disjoint in *. intros.
apply H; simpl in *; auto.
induction p.
simpl in *. rewrite PTree.gsspec. if_tac. intuition.
auto.
simpl in *. repeat rewrite PTree.gsspec in *. destruct a.
simpl in *. if_tac. auto. rewrite IHp. auto. unfold list_disjoint in *.
intros. apply H; simpl in *; auto.
simpl in *. rewrite PTree.gsspec in *. if_tac.
subst.
induction p.
simpl in *. rewrite PTree.gsspec in *. rewrite peq_true in *.
auto.
simpl in *. rewrite PTree.gsspec in *. destruct a0. simpl in *.
if_tac. subst. clear - H. specialize (H p0 p0). intuition. apply IHp.
unfold list_disjoint in *. intros. apply H; simpl in *; auto.
intros. apply IHt. unfold list_disjoint in *. intros; simpl in *; apply H; auto.
auto. auto. intuition.
destruct a. simpl in *. induction p.
simpl in *. rewrite PTree.gsspec. if_tac; subst. intuition.
repeat rewrite PTree.gsspec. auto.
simpl in *. destruct a. simpl in *.
spec IHt. unfold list_disjoint in *. intros; apply H; simpl in *; auto.
intuition.
repeat rewrite PTree.gsspec in *. if_tac.
subst. auto.
apply IHp. unfold list_disjoint in *. intros. apply H. simpl in *.
auto. auto. intros. auto.
Qed.
Lemma func_tycontext_t_sound : func_tycontext_t_denote.
unfold func_tycontext_t_denote.
split; intros;
unfold make_tycontext_t in *;
apply list_norepet_app in H; destruct H as [? [? ?]].
induction t; induction p; simpl in *.
rewrite PTree.gempty in *; congruence.
left. destruct a; simpl in *. rewrite PTree.gsspec in *. if_tac in H0.
inv H0. auto.
inv H. destruct IHp; auto. unfold list_disjoint. intros. inv H4.
destruct H. subst. auto. intuition.
right. destruct a. simpl in *. rewrite PTree.gsspec in *.
if_tac in H0. subst. inv H0. auto. destruct IHt. inv H1; auto.
unfold list_disjoint in *. intros. inv H4. auto. intuition. intuition.
simpl in *. rewrite PTree.gsspec in *. if_tac in H0. destruct a0. simpl in *.
subst. inv H0. intuition. destruct a0. simpl in *. destruct a. simpl in *.
destruct IHp. inv H; auto. intro; intros. apply H2; simpl in *; auto.
auto. intros. destruct IHt. inv H1; auto. intro; intros; apply H2; simpl in *; auto.
auto. destruct H7. destruct H7. inv H7. intuition. auto. auto. left.
split. right. apply H4. apply H4. right. auto.
induction t; induction p; simpl in *.
intuition.
rewrite PTree.gsspec. if_tac. subst. destruct a. simpl in *.
destruct H0. destruct H0. destruct H0. inv H0. auto. subst.
clear - H H0. inv H. rewrite in_map_iff in *. destruct H3.
exists (i,ty). auto. inv H0. inv H3. destruct H0. destruct H0.
destruct a. destruct H0. subst. inv H0. intuition.
simpl in *. apply IHp. inv H; auto. intro. intros. inv H6. left.
subst. auto. destruct H0. inv H0. destruct H0. destruct H0. destruct H0.
destruct H0. destruct H0. destruct a. simpl in *. inv H0; subst.
rewrite PTree.gsspec. rewrite peq_true. auto. subst.
destruct a. simpl in *. rewrite PTree.gsspec. if_tac.
subst. clear -H0 H1. inv H1. rewrite in_map_iff in *.
destruct H3. exists (i,ty); auto. apply IHt. inv H1; auto.
intro; auto. right. auto.
spec IHt. inv H1; auto. spec IHt. intro; intros; apply H2; simpl in *; auto.
spec IHp. inv H; auto. spec IHp. intro; intros; apply H2; simpl in *; auto.
destruct a. destruct a0. destruct H0. simpl in *.
destruct H0. destruct H0. inv H0.
rewrite PTree.gsspec in *. rewrite peq_true. auto. subst.
rewrite PTree.gsspec in *. if_tac. subst. inv H. rewrite in_map_iff in H5.
destruct H5. exists (i0,ty); auto. spec IHp. auto. spec IHp; auto.
simpl in *. rewrite PTree.gsspec. if_tac. subst. destruct H0. destruct H0.
inv H0. specialize (H2 i0 i0). destruct H2; simpl; auto. subst.
spec IHt. auto. rewrite PTree.gsspec in *. rewrite peq_true in *. auto.
destruct H0. destruct H0. inv H0. spec IHp. auto.
spec IHp; auto. intros; auto. destruct H5. destruct H5; congruence. destruct H5.
clear - H5 H1. inv H1. destruct H2. apply in_map_iff. exists (id, ty). auto. subst.
spec IHp. auto. spec IHp; auto. spec IHt; auto. rewrite PTree.gsspec in *.
if_tac in IHt. intuition. intros. auto.
Qed.
Definition cast_no_val_change (from: type)(to:type) : bool :=
match from, to with
| Tint _ _ _, Tint I32 _ _ => true
| Tpointer _ _, Tpointer _ _ => true
| Tfloat _ _ , Tfloat F64 _ => true
| _, _ => false
end.
Lemma cast_no_change : forall v from to,
is_true (typecheck_val v from) ->
is_true (cast_no_val_change from to) ->
Cop.sem_cast v from to = Some v.
Proof.
intros. destruct v; destruct from; simpl in *; try congruence; destruct to; simpl in *; try congruence; auto;
try destruct i1; try destruct f1; simpl in *; try congruence; auto.
Qed.
Lemma tc_exprlist_length : forall Delta tl el rho,
denote_tc_assert (typecheck_exprlist Delta tl el) rho ->
length tl = length el.
Proof.
intros. generalize dependent el. induction tl; intros. simpl in *. destruct el. inv H. auto.
inv H. simpl in H. destruct el; try solve [inv H]. simpl in *.
repeat( rewrite tc_andp_sound in *; simpl in *; super_unfold_lift).
super_unfold_lift.
intuition.
Qed.
Lemma neutral_cast_typecheck_val : forall e t rho Delta,
true = is_neutral_cast (typeof e) t ->
denote_tc_assert (isCastResultType (typeof e) t t e) rho ->
denote_tc_assert (typecheck_expr Delta e) rho ->
typecheck_environ Delta rho ->
typecheck_val (eval_expr e rho) t = true.
Proof.
intros.
rewrite isCastR in H0.
apply typecheck_expr_sound in H1; auto.
destruct (typeof e); destruct t; simpl in H; simpl in H0;
try congruence; remember (eval_expr e rho); destruct v;
simpl in H0; try congruence; auto;
destruct i; destruct s; try destruct i0; try destruct s0;
unfold is_neutral_cast in *;
simpl in *; try congruence; super_unfold_lift;
try rewrite <- Heqv in *; unfold denote_tc_iszero in *;
try apply H0; try contradiction.
Qed.
Lemma allowed_val_cast_sound : forall v tfrom tto,
allowedValCast v tfrom tto = true ->
typecheck_val v tfrom = true ->
typecheck_val v tto = true.
Proof.
intros.
destruct v; destruct tfrom; destruct tto; try solve [simpl in *; try congruence]; auto; first [destruct i1 | destruct i0 | destruct i]; try destruct s; unfold allowedValCast in *; try solve [simpl in *; try congruence].
Qed.
Definition typecheck_tid_ptr_compare
Delta id :=
match (temp_types Delta) ! id with
| Some (t, _) =>
is_int_type t
| None => false
end.
Lemma typecheck_tid_ptr_compare_sub:
forall Delta Delta',
tycontext_sub Delta Delta' ->
forall id, typecheck_tid_ptr_compare Delta id = true ->
typecheck_tid_ptr_compare Delta' id = true.
Proof.
unfold typecheck_tid_ptr_compare;
intros.
destruct H as [? _].
specialize (H id).
destruct ((temp_types Delta) ! id) as [[? ?]|]; try discriminate.
destruct ((temp_types Delta') ! id) as [[? ?]|]; try contradiction.
destruct H; subst; auto.
Qed.
Lemma tycontext_sub_refl:
forall Delta, tycontext_sub Delta Delta.
Proof.
intros. destruct Delta as [[[T V] r] G].
unfold tycontext_sub.
intuition.
+ unfold sub_option. unfold temp_types. simpl.
destruct (T ! id) as [[? ?]|]; split; auto; destruct b; auto.
+ unfold sub_option, glob_types. simpl.
destruct (G ! id); auto.
Qed.
Lemma initialized_ne : forall Delta id1 id2,
id1 <> id2 ->
(temp_types Delta) ! id1 = (temp_types (initialized id2 Delta)) ! id1.
intros.
destruct Delta as [[[? ?] ?] ?]. unfold temp_types; simpl.
unfold initialized. simpl. unfold temp_types; simpl.
destruct (t ! id2). destruct p. simpl. rewrite PTree.gso; auto.
auto.
Qed.
Lemma initialized_sub :
forall Delta Delta' i ,
tycontext_sub Delta Delta' ->
tycontext_sub (initialized i Delta) (initialized i Delta').
Proof.
intros.
unfold tycontext_sub in *.
destruct H as [? [? [? ?]]].
repeat split; intros.
+ specialize (H id); clear - H.
destruct (eq_dec i id).
- unfold initialized. subst.
destruct ((temp_types Delta)!id) as [[? ?] |] eqn:?.
unfold temp_types at 1; simpl; rewrite PTree.gss.
destruct ((temp_types Delta')!id) as [[? ?] |]. destruct H; subst t0.
unfold temp_types at 1. simpl. rewrite PTree.gss. auto. contradiction.
rewrite Heqo. auto.
- rewrite <- initialized_ne by auto.
destruct ((temp_types Delta)!id) as [[? ?] |] eqn:?; auto.
rewrite <- initialized_ne by auto.
destruct ((temp_types Delta')!id) as [[? ?] |]; [| contradiction].
auto.
+ repeat rewrite set_temp_ve; auto.
+ repeat rewrite set_temp_ret; auto.
+ repeat rewrite set_temp_ge; auto.
Qed.
Definition te_one_denote (v1 v2 : option (type * bool)):=
match v1, v2 with
| Some (t1,b1),Some (t2, b2) => Some (t1, andb b1 b2)
| _, _ => None
end.
Lemma join_te_denote2:
forall d1 d2 id,
((join_te d1 d2) ! id) = te_one_denote (d1 ! id) (d2 ! id).
Proof.
intros. remember (d1 ! id). remember (d2 ! id).
destruct o; destruct o0.
- unfold te_one_denote. destruct p; destruct p0.
remember (eqb_type t t0). destruct b1.
+ symmetry in Heqb1. apply eqb_type_true in Heqb1.
subst. apply join_te_eqv; auto.
+ unfold join_te.
Admitted.
Lemma tycontext_sub_join:
forall Delta1 Delta2 Delta1' Delta2',
tycontext_sub Delta1 Delta1' -> tycontext_sub Delta2 Delta2' ->
tycontext_sub (join_tycon Delta1 Delta2) (join_tycon Delta1' Delta2').
Proof.
intros [[[A1 B1] C1] D1] [[[A2 B2] C2] D2] [[[A1' B1'] C1'] D1'] [[[A2' B2'] C2'] D2']
[? [? [? ?]]] [? [? [? ?]]].
simpl in *.
unfold join_tycon.
split; [ | split; [ | split]]; simpl; auto.
intro id; specialize (H id); specialize (H3 id).
unfold temp_types in *.
simpl in *.
clear - H H3.
unfold sub_option in *.
repeat rewrite join_te_denote2.
unfold te_one_denote.
destruct (A1 ! id) as [[? b1] |].
destruct (A1' ! id) as [[? b1'] |]; [ | contradiction].
destruct H; subst t0.
destruct (A2 ! id) as [[? b2] |].
destruct (A2' ! id) as [[? b2'] |]; [ | contradiction].
destruct H3; subst t1.
split; auto. destruct b1,b1'; inv H0; simpl; auto.
destruct (A2' ! id) as [[? b2'] |]; split; auto.
auto.
Qed.
Lemma temp_types_same_type' : forall i (Delta: tycontext),
(temp_types (initialized i Delta)) ! i =
match (temp_types Delta) ! i with
| Some (t, b) => Some (t, true)
| None => None
end.
Proof.
intros.
unfold initialized.
destruct ((temp_types Delta) ! i) as [[? ?]|] eqn:?.
unfold temp_types at 1. simpl. rewrite PTree.gss. auto.
auto.
Qed.
Lemma update_tycon_sub:
forall Delta Delta', tycontext_sub Delta Delta' ->
forall h, tycontext_sub (update_tycon Delta h) (update_tycon Delta' h).
Proof.
intros.
destruct H as [? [? [? ?]]].
repeat split; intros; auto.
+ clear - H.
generalize dependent Delta.
revert h id Delta'.
induction h; intros; try apply H; simpl; try destruct o;
auto.
- destruct (eq_dec id i). subst.
rewrite temp_types_same_type'.
specialize (H i).
destruct ((temp_types Delta) ! i) as [[? ?]|] eqn:?.
rewrite temp_types_same_type'.
destruct ((temp_types Delta') ! i) as [[? ?]|] eqn:?; [ | contradiction].
destruct H; subst t0. split; auto. auto.
specialize (H id).
rewrite <- initialized_ne by auto.
destruct ((temp_types Delta) ! id) as [[? ?]|] eqn:?; auto.
rewrite <- initialized_ne by auto.
destruct ((temp_types Delta') ! id) as [[? ?]|] eqn:?; auto.
- repeat rewrite temp_types_update_dist.
specialize (H id).
destruct (eq_dec id i). subst.
rewrite temp_types_same_type'.
destruct ((temp_types Delta) ! i) as [[? ?]|] eqn:?; auto.
rewrite temp_types_same_type'.
destruct ((temp_types Delta') ! i) as [[? ?]|] eqn:?; [ | contradiction].
destruct H; subst t0. split; auto. auto.
rewrite <- initialized_ne by auto.
destruct ((temp_types Delta) ! id) as [[? ?]|] eqn:?; auto.
rewrite <- initialized_ne by auto.
destruct ((temp_types Delta') ! id) as [[? ?]|] eqn:?; auto.
-
Admitted.