Module TypesDomain


Abstract domain for simple type reconstruction.

Require Import Coqlib Utf8.
Require Import Globalenvs.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import AST.
Require Import ToString.
Require Import Util.
Require Import AdomLib.
Require Import Cminor.
Require Import PExpr.

Module AbTy.


  Definition t := PExpr.typ.

  Instance ty_leb : leb_op t := fun x y =>
    match x, y with
      | VI, VI
      | VP, VP
      | VIP, VIP
      | VL, VL
      | VF, VF
      | VS, VS
      | (VI | VP), VIP => true
      | _, _ => false
    end.

  Instance ty_join : join_op t (t+⊤) := fun x y =>
    match x, y with
      | VI, VI => Just VI
      | VP, VP => Just VP
      | (VIP|VP), (VIP|VI)
      | (VIP|VI), VP | VI, VIP => Just VIP
      | VL, VL => Just VL
      | VF, VF => Just VF
      | VS, VS => Just VS
      | _, _ => All
    end.

  Definition ty_widen := ty_join.

  Instance ty_leb_correct : leb_op_correct t val.
Proof.
repeat intro. destruct a1, a2, a, H0; try constructor; discriminate. Qed.

  Instance ty_join_correct : join_op_correct t (t+⊤) val.
Proof.
repeat intro. destruct x, y, a; try constructor; destruct H as [[]|[]]. Qed.

  Definition eval_constant (cst: constant) : t :=
    match cst with
      | Ointconst n => VI
      | Ofloatconst n => VF
      | Osingleconst n => VS
      | Olongconst n => VL
      | Oaddrsymbol s ofs => VP
    end.

  Definition eval_unop (op: unary_operation) (arg: t) : t :=
    match op with
      | Ocast8unsigned | Ocast8signed | Ocast16unsigned | Ocast16signed
      | Onegint | Onotint | Ointoffloat | Ointuoffloat | Ointofsingle
      | Ointuofsingle | Ointoflong => VI
      | Onegf | Oabsf | Ofloatofsingle | Ofloatofint | Ofloatofintu
      | Ofloatoflong | Ofloatoflongu => VF
      | Onegl | Onotl | Olongofint | Olongofintu | Olongoffloat
      | Olonguoffloat | Olongofsingle | Olonguofsingle => VL
      | Onegfs | Oabsfs | Osingleoffloat | Osingleofint | Osingleofintu
      | Osingleoflong | Osingleoflongu => VS
  end.

  Definition eval_binop (op: binary_operation) (arg1 arg2: t): t :=
    match op with
    | Oadd =>
      match arg1, arg2 with
      | VP, VI
      | VI, VP => VP
      | VI, VI => VI
      | _, _ => VIP
      end
    | Osub =>
      match arg1, arg2 with
      | VP, VI => VP
      | VP, VP
      | VI, VI => VI
      | _, _ => VIP
      end
    | Omul | Odiv | Odivu | Omod | Omodu | Oand | Oor | Oxor | Oshl
    | Oshr | Oshru | Ocmp _ | Ocmpu _ | Ocmpf _ | Ocmpfs _ | Ocmpl _ | Ocmplu _ => VI
    | Oaddf | Osubf | Omulf | Odivf => VF
    | Oaddfs | Osubfs | Omulfs | Odivfs => VS
    | Oaddl | Osubl | Omull | Odivl | Odivlu | Omodl | Omodlu | Oandl
    | Oorl | Oxorl | Oshll | Oshrl | Oshrlu => VL
    end.

  Lemma eval_constant_correct F V : forall (ge: Genv.t F V) c v,
    pexpr_eval_constant ge c = v ->
    vVundef
    γ (eval_constant c) v.
Proof.
    destruct c; simpl; intros v Hv; inv Hv; try easy.
    destruct Genv.find_symbol. intro; exact I.
    intros K; elim (K eq_refl).
  Qed.

  Lemma eval_unop_correct : forall op arg x v,
    Cminor.eval_unop op arg = Some v ->
    vVundef
    γ x arg ->
    γ (eval_unop op x) v.
Proof.
    destruct op; destruct arg; simpl; intros x v Hv U;
    try (destruct (Float.to_int f));
    try (destruct (Float.to_intu f));
    try (destruct (Float.to_long f));
    try (destruct (Float.to_longu f));
    try (destruct (Float32.to_int f));
    try (destruct (Float32.to_intu f));
    try (destruct (Float32.to_long f));
    try (destruct (Float32.to_longu f));
    simpl in Hv;
    eq_some_inv; subst;
    (try (intros _; exact I));
    congruence.
  Qed.

  Lemma gamma_Vint_inv {x : t} {i} : γ x (Vint i) →
    x = VIx = VIP.
Proof.
destruct x; intuition. Qed.

  Lemma gamma_VI_inv {v} :
    γ VI v → ∃ i, v = Vint i.
Proof.
destruct v; intros (). vauto. Qed.

  Lemma gamma_Vptr_inv {x : t} {b i} : γ x (Vptr b i) →
    x = VPx = VIP.
Proof.
destruct x; intuition. Qed.

  Lemma gamma_VP_inv {v} :
    γ VP v → ∃ b i, v = Vptr b i.
Proof.
destruct v; intros (); vauto. Qed.

  Lemma gamma_VIP_inv {v} :
    γ VIP v → (∃ b i, v = Vptr b i) ∨ (∃ i, v = Vint i).
Proof.
destruct v; intros (); vauto. Qed.

  Lemma gamma_Vfloat_inv {x : t} {f} : γ x (Vfloat f) → x = VF.
Proof.
destruct x; intuition. Qed.

  Lemma gamma_Vsingle_inv {x : t} {f} : γ x (Vsingle f) → x = VS.
Proof.
destruct x; intuition. Qed.

  Lemma gamma_VF_inv {v} :
    v ∈ γ VF → ∃ f, v = Vfloat f.
Proof.
destruct v; intros (); vauto. Qed.

  Lemma gamma_VS_inv {v} :
    v ∈ γ VS → ∃ f, v = Vsingle f.
Proof.
destruct v; intros (); vauto. Qed.

  Lemma gamma_Vlong_inv {x : t} {l} : γ x (Vlong l) → x = VL.
Proof.
destruct x; intuition. Qed.

  Lemma gamma_VL_inv {v} :
    v ∈ γ VL → ∃ l, v = Vlong l.
Proof.
destruct v; intros (); vauto. Qed.

  Lemma gamma_Vundef_inv {x: t} : γ x VundefFalse.
Proof.
destruct x; intuition. Qed.

  Ltac gamma_inv :=
    repeat
      match goal with
      | H : gamma_typ ?a ?b |- _ => changea b) in H
      | H : γ _ (Vint _) |- _ => apply gamma_Vint_inv in H
      | H : γ VI _ |- _ => apply gamma_VI_inv in H
      | H : γ _ (Vptr _ _) |- _ => apply gamma_Vptr_inv in H
      | H : γ VP _ |- _ => apply gamma_VP_inv in H
      | H : γ VIP _ |- _ => apply gamma_VIP_inv in H
      | H : γ _ (Vfloat _) |- _ => apply gamma_Vfloat_inv in H
      | H : γ VF _ |- _ => apply gamma_VF_inv in H
      | H : γ _ (Vsingle _) |- _ => apply gamma_Vsingle_inv in H
      | H : γ VS _ |- _ => apply gamma_VS_inv in H
      | H : γ _ (Vlong _) |- _ => apply gamma_Vlong_inv in H
      | H : γ VL _ |- _ => apply gamma_VL_inv in H
      | H : γ _ Vundef |- _ => apply gamma_Vundef_inv in H
      end.

  Lemma if_opt {A: Type} (b: bool) (a a': A) :
    (if b then Some a else None) = Some a' →
    a = a' ∧ b = true.
Proof.
bif; intros; eq_some_inv; vauto. Qed.

  Lemma eval_binop_correct : forall op arg1 arg2 x1 x2 m v,
    Cminor.eval_binop op arg1 arg2 m = Some v ->
    vVundef
    γ x1 arg1 ->
    γ x2 arg2 ->
    γ (eval_binop op x1 x2) v.
Proof.
    intros [] [] [] x1 x2 m v Hv Hvdef Hx1 Hx2; simpl in Hv;
    symmetry in Hv;
    repeat match goal with
      | c: comparison |- _ =>
        destruct c;
        unfold Val.cmp, Val.cmpu, Val.cmplu, Val.cmpf, Val.cmpfs, Val.cmpl, Val.of_bool in Hv;
        simpl in Hv
      | Hv : Some v = Some _ |- _ => eq_some_inv
      | Hv : Some v = None |- _ => eq_some_inv
      | Hv : v = Vundef |- _ => now destruct (Hvdef Hv)
      | Hv : _ = if ?c then _ else _ |- _ => destruct c eqn:?
    end;
    try (subst v; destruct x1, Hx1, x2, Hx2; exact I).
    simpl. subst. revert Hvdef. bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif. easy. intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif; intros X; elim (X eq_refl).
    simpl. subst. revert Hvdef. bif. bif. simpl. bif; easy.
    intros X; elim (X eq_refl).
    bif; intros X; elim (X eq_refl).
  Qed.

End AbTy.