diff options
author | Sylvain Boulmé <sylvain.boulme@univ-grenoble-alpes.fr> | 2020-10-08 17:33:47 +0200 |
---|---|---|
committer | Sylvain Boulmé <sylvain.boulme@univ-grenoble-alpes.fr> | 2020-10-08 17:33:47 +0200 |
commit | 7d3f90f10386112907f252c1ee5d9046a9220eb0 (patch) | |
tree | a8c9e233e013695e6c4a32adaa2f2ac11bc87430 /kvx | |
parent | 141ae136e02f2a0fff469f8c8106e156477963ad (diff) | |
download | compcert-kvx-7d3f90f10386112907f252c1ee5d9046a9220eb0.tar.gz compcert-kvx-7d3f90f10386112907f252c1ee5d9046a9220eb0.zip |
Restart the proof with cherry-pick from Cyril and commit 0e4186b8f
Diffstat (limited to 'kvx')
-rw-r--r-- | kvx/lib/RTLpathSE_impl_junk.v | 2218 | ||||
-rw-r--r-- | kvx/lib/RTLpathSE_theory.v | 10 |
2 files changed, 433 insertions, 1795 deletions
diff --git a/kvx/lib/RTLpathSE_impl_junk.v b/kvx/lib/RTLpathSE_impl_junk.v index 24da159a..2ea3e1ee 100644 --- a/kvx/lib/RTLpathSE_impl_junk.v +++ b/kvx/lib/RTLpathSE_impl_junk.v @@ -20,28 +20,10 @@ Local Open Scope impure. Import ListNotations. Local Open Scope list_scope. -Ltac wlp_intro vname hname := apply wlp_unfold; intros vname hname. -Ltac wlp_bind vname hname := apply wlp_bind; intros vname hname. -Ltac wlp_ret vname := let H := fresh "H" vname in wlp_intro vname H; apply mayRet_ret in H; subst. - -Tactic Notation "wlp_intro" ident(v) ident(h) := wlp_intro v h. -Tactic Notation "wlp_intro" ident(v) := let H := fresh "H" v in wlp_intro v H. -Tactic Notation "wlp_bind" ident(v) ident(h) := wlp_bind v h. -Tactic Notation "wlp_bind" ident(v) := let H := fresh "H" v in wlp_bind v H. - -Ltac wlp_absurd := match goal with - | [ H : FAILWITH ?msg |- _ ] => eapply (_FAILWITH_correct _ _ (fun _ => False)) in H; inv H - | [ H : DO r <~ fail ?msg;; RET ?expr ~~> ?exta |- _ ] => eapply (_FAILWITH_correct _ _ (fun _ => False)) in H; inv H -end. - -Ltac wlp_hbind var := match goal with - | [ H : DO _ <~ ?expr;; _ ~~> _ |- _ ] => - let Hvar := fresh "H" var in (apply mayRet_bind in H; destruct H as (var & Hvar & H)) - end. +Definition XDEBUG {A} (x:A) (k: A -> ?? pstring): ?? unit := RET tt. (* TO REMOVE DEBUG INFO *) +(* Definition XDEBUG {A} (x:A) (k: A -> ?? pstring): ?? unit := DO s <~ k x;; println ("DEBUG simu_check:" +; s). (* TO INSERT DEBUG INFO *) *) -Ltac wlp_hret := match goal with - | [ H : RET _ ~~> _ |- _ ] => apply mayRet_ret in H; subst; clear H - end. +Definition DEBUG (s: pstring): ?? unit := XDEBUG tt (fun _ => RET s). (** * Implementation of Data-structure use in Hash-consing *) @@ -100,6 +82,7 @@ Definition hsmem_set_hid (hsm: hsmem) (hid: hashcode): hsmem := | HSstore hsm chunk addr lhsv srce _ => HSstore hsm chunk addr lhsv srce hid end. + (** Now, we build the hash-Cons value from a "hash_eq". Informal specification: @@ -162,7 +145,9 @@ Program Definition mk_hash_params: Dict.hash_params hsval := {| Dict.test_eq := phys_eq; Dict.hashing := fun (ht: hsval) => RET (hsval_get_hid ht); - Dict.log := fun _ => RET () (* NB no log *) |}. + Dict.log := fun hv => + DO hv_name <~ string_of_hashcode (hsval_get_hid hv);; + println ("unexpected undef behavior of hashcode:" +; (CamlStr hv_name)) |}. Obligation 1. wlp_simplify. Qed. @@ -207,6 +192,8 @@ Record hsistate := { hsi_pc: node; hsi_exits: list hsistate_exit; hsi_local: hsi (** ** Syntax and Semantics of symbolic state *) Record hsstate := { hinternal:> hsistate; hfinal: hsfval }. +(** ** Refinement Definitions: from refinement of symbolic values, memories, local/exit/internal/symbolic. *) + Fixpoint hsval_proj hsv := match hsv with | HSinput r _ => Sinput r @@ -224,30 +211,163 @@ with hsmem_proj hm := | HSstore hm chk addr hl hv _ => Sstore (hsmem_proj hm) chk addr (hsval_list_proj hl) (hsval_proj hv) end. +(** We use a Notation instead a Definition, in order to get more automation "for free" *) +Local Notation "'seval_hsval' ge sp hsv" := (seval_sval ge sp (hsval_proj hsv)) + (only parsing, at level 0, ge at next level, sp at next level, hsv at next level). +Local Notation "'seval_list_hsval' ge sp lhv" := (seval_list_sval ge sp (hsval_list_proj lhv)) + (only parsing, at level 0, ge at next level, sp at next level, lhv at next level). +Local Notation "'seval_hsmem' ge sp hsm" := (seval_smem ge sp (hsmem_proj hsm)) + (only parsing, at level 0, ge at next level, sp at next level, hsm at next level). + +Lemma hseval_preserved ge ge' rs0 m0 sp hsv: + (forall s, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> + seval_hsval ge sp hsv rs0 m0 = seval_hsval ge' sp hsv rs0 m0. +Proof. + intros; eapply seval_preserved; eauto. +Qed. + +Lemma hsmem_eval_preserved ge ge' rs0 m0 sp hsm: + (forall s, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> + seval_hsmem ge sp hsm rs0 m0 = seval_hsmem ge' sp hsm rs0 m0. +Proof. + intros; eapply smem_eval_preserved; eauto. +Qed. + + +Local Notation "'sval_refines' ge sp rs0 m0 hv sv" := (seval_hsval ge sp hv rs0 m0 = seval_sval ge sp sv rs0 m0) + (only parsing, at level 0, ge at next level, sp at next level, rs0 at next level, m0 at next level, hv at next level, sv at next level). + +Local Notation "'list_sval_refines' ge sp rs0 m0 lhv lsv" := (seval_list_hsval ge sp lhv rs0 m0 = seval_list_sval ge sp lsv rs0 m0) + (only parsing, at level 0, ge at next level, sp at next level, rs0 at next level, m0 at next level, lhv at next level, lsv at next level). + +Local Notation "'smem_refines' ge sp rs0 m0 hm sm" := (seval_hsmem ge sp hm rs0 m0 = seval_smem ge sp sm rs0 m0) + (only parsing, at level 0, ge at next level, sp at next level, rs0 at next level, m0 at next level, hm at next level, sm at next level). + +Definition hsi_sreg_eval ge sp (hst: PTree.t hsval) r rs0 m0: option val := + match PTree.get r hst with + | None => Some (Regmap.get r rs0) + | Some hsv => seval_sval ge sp (hsval_proj hsv) rs0 m0 + end. + +Definition hsok_local ge sp rs0 m0 (hst: hsistate_local) : Prop := + (forall hsv, List.In hsv (hsi_ok_lsval hst) -> seval_hsval ge sp hsv rs0 m0 <> None) + /\ (seval_hsmem ge sp (hst.(hsi_smem)) rs0 m0 <> None). + +(* refinement link between a (st: sistate_local) and (hst: hsistate_local) *) +Definition hsilocal_refines ge sp rs0 m0 (hst: hsistate_local) (st: sistate_local) := + (sok_local ge sp rs0 m0 st <-> hsok_local ge sp rs0 m0 hst) + /\ (hsok_local ge sp rs0 m0 hst -> smem_refines ge sp rs0 m0 (hsi_smem hst) (st.(si_smem))) + /\ (hsok_local ge sp rs0 m0 hst -> forall r, hsi_sreg_eval ge sp hst r rs0 m0 = seval_sval ge sp (si_sreg st r) rs0 m0) + /\ (forall r sv, hst ! r = Some sv -> In sv (hsi_ok_lsval hst)). + +(* +Lemma ssem_local_sok ge sp rs0 m0 st rs m: + ssem_local ge sp st rs0 m0 rs m -> sok_local ge sp rs0 m0 st. +Proof. + unfold sok_local, ssem_local. + intuition congruence. +Qed. + +Lemma ssem_local_refines_hok ge sp rs0 m0 hst st rs m: + ssem_local ge sp st rs0 m0 rs m -> hsilocal_refines ge sp rs0 m0 hst st -> hsok_local ge sp rs0 m0 hst. +Proof. + intros H0 (H1 & _ & _). apply H1. eapply ssem_local_sok. eauto. +Qed. +*) + +(** NB: we split the refinement relation between a "static" part -- independendent of the initial context + and a "dynamic" part -- that depends on it +*) +Definition hsiexit_refines_stat (hext: hsistate_exit) (ext: sistate_exit): Prop := + hsi_ifso hext = si_ifso ext. + +Definition hsok_exit ge sp rs m hse := hsok_local ge sp rs m (hsi_elocal hse). + +Definition hseval_condition ge sp cond hcondargs hmem rs0 m0 := + seval_condition ge sp cond (hsval_list_proj hcondargs) (hsmem_proj hmem) rs0 m0. + +Lemma hseval_condition_preserved ge ge' sp cond args mem rs0 m0: + (forall s : ident, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> + hseval_condition ge sp cond args mem rs0 m0 = hseval_condition ge' sp cond args mem rs0 m0. +Proof. + intros. unfold hseval_condition. erewrite seval_condition_preserved; [|eapply H]. + reflexivity. +Qed. + +Definition hsiexit_refines_dyn ge sp rs0 m0 (hext: hsistate_exit) (ext: sistate_exit): Prop := + hsilocal_refines ge sp rs0 m0 (hsi_elocal hext) (si_elocal ext) + /\ (hsok_local ge sp rs0 m0 (hsi_elocal hext) -> + hseval_condition ge sp (hsi_cond hext) (hsi_scondargs hext) (hsi_smem (hsi_elocal hext)) rs0 m0 + = seval_condition ge sp (si_cond ext) (si_scondargs ext) (si_smem (si_elocal ext)) rs0 m0). + +Definition hsiexits_refines_stat lhse lse := + list_forall2 hsiexit_refines_stat lhse lse. + +Definition hsiexits_refines_dyn ge sp rs0 m0 lhse se := + list_forall2 (hsiexit_refines_dyn ge sp rs0 m0) lhse se. + + +Inductive nested_sok ge sp rs0 m0: sistate_local -> list sistate_exit -> Prop := + nsok_nil st: nested_sok ge sp rs0 m0 st nil + | nsok_cons st se lse: + (sok_local ge sp rs0 m0 st -> sok_local ge sp rs0 m0 (si_elocal se)) -> + nested_sok ge sp rs0 m0 (si_elocal se) lse -> + nested_sok ge sp rs0 m0 st (se::lse). + +Lemma nested_sok_prop ge sp st sle rs0 m0: + nested_sok ge sp rs0 m0 st sle -> + sok_local ge sp rs0 m0 st -> + forall se, In se sle -> sok_local ge sp rs0 m0 (si_elocal se). +Proof. + induction 1; simpl; intuition (subst; eauto). +Qed. + +Lemma nested_sok_elocal ge sp rs0 m0 st2 exits: + nested_sok ge sp rs0 m0 st2 exits -> + forall st1, (sok_local ge sp rs0 m0 st1 -> sok_local ge sp rs0 m0 st2) -> + nested_sok ge sp rs0 m0 st1 exits. +Proof. + induction 1; [intros; constructor|]. + intros. constructor; auto. +Qed. + +Lemma nested_sok_tail ge sp rs0 m0 st lx exits: + is_tail lx exits -> + nested_sok ge sp rs0 m0 st exits -> + nested_sok ge sp rs0 m0 st lx. +Proof. + induction 1; [auto|]. + intros. inv H0. eapply IHis_tail. eapply nested_sok_elocal; eauto. +Qed. + +Definition hsistate_refines_stat (hst: hsistate) (st:sistate): Prop := + hsi_pc hst = si_pc st + /\ hsiexits_refines_stat (hsi_exits hst) (si_exits st). + +Definition hsistate_refines_dyn ge sp rs0 m0 (hst: hsistate) (st:sistate): Prop := + hsiexits_refines_dyn ge sp rs0 m0 (hsi_exits hst) (si_exits st) + /\ hsilocal_refines ge sp rs0 m0 (hsi_local hst) (si_local st) + /\ nested_sok ge sp rs0 m0 (si_local st) (si_exits st). + + (** * Implementation of symbolic execution *) Section CanonBuilding. Variable hC_hsval: hashinfo hsval -> ?? hsval. -(** FIXME - maybe it's not what we want ? *) -Hypothesis hC_hsval_correct: forall hs rhsv, - hC_hsval hs ~~> rhsv -> - (hsval_proj (hdata hs)) = (hsval_proj rhsv). -Local Hint Resolve hC_hsval_correct: wlp. +Hypothesis hC_hsval_correct: forall hs, + WHEN hC_hsval hs ~> hs' THEN forall ge sp rs0 m0, + seval_hsval ge sp (hdata hs) rs0 m0 = seval_hsval ge sp hs' rs0 m0. Variable hC_list_hsval: hashinfo list_hsval -> ?? list_hsval. - -Hypothesis hC_list_hsval_correct: forall hs rhsv, - hC_list_hsval hs ~~> rhsv -> - (hsval_list_proj (hdata hs)) = (hsval_list_proj rhsv). -Local Hint Resolve hC_list_hsval_correct: wlp. +Hypothesis hC_list_hsval_correct: forall lh, + WHEN hC_list_hsval lh ~> lh' THEN forall ge sp rs0 m0, + seval_list_hsval ge sp (hdata lh) rs0 m0 = seval_list_hsval ge sp lh' rs0 m0. Variable hC_hsmem: hashinfo hsmem -> ?? hsmem. - -Hypothesis hC_hsmem_correct: forall hs rhsv, - hC_hsmem hs ~~> rhsv -> - (hsmem_proj (hdata hs)) = (hsmem_proj rhsv). -Local Hint Resolve hC_hsmem_correct: wlp. +Hypothesis hC_hsmem_correct: forall hm, + WHEN hC_hsmem hm ~> hm' THEN forall ge sp rs0 m0, + seval_hsmem ge sp (hdata hm) rs0 m0 = seval_hsmem ge sp hm' rs0 m0. (* First, we wrap constructors for hashed values !*) @@ -265,6 +385,15 @@ Definition hSinput (r:reg): ?? hsval := DO hv <~ hSinput_hcodes r;; hC_hsval {| hdata:=HSinput r unknown_hid; hcodes :=hv; |}. +Lemma hSinput_correct r: + WHEN hSinput r ~> hv THEN forall ge sp rs0 m0, + sval_refines ge sp rs0 m0 hv (Sinput r). +Proof. + wlp_simplify. +Qed. +Global Opaque hSinput. +Local Hint Resolve hSinput_correct: wlp. + Definition hSop_hcodes (op:operation) (lhsv: list_hsval) (hsm: hsmem) := DO hc <~ hash op_hcode;; DO hv <~ hash op;; @@ -275,6 +404,19 @@ Definition hSop (op:operation) (lhsv: list_hsval) (hsm: hsmem): ?? hsval := DO hv <~ hSop_hcodes op lhsv hsm;; hC_hsval {| hdata:=HSop op lhsv hsm unknown_hid; hcodes :=hv |}. +Lemma hSop_correct op lhsv hsm: + WHEN hSop op lhsv hsm ~> hv THEN forall ge sp rs0 m0 lsv sm, + list_sval_refines ge sp rs0 m0 lhsv lsv -> + smem_refines ge sp rs0 m0 hsm sm -> + sval_refines ge sp rs0 m0 hv (Sop op lsv sm). +Proof. + wlp_simplify. + rewrite <- H0, <- H1. + auto. +Qed. +Global Opaque hSop. +Local Hint Resolve hSop_correct: wlp. + Definition hSload_hcodes (hsm: hsmem) (trap: trapping_mode) (chunk: memory_chunk) (addr: addressing) (lhsv: list_hsval):= DO hc <~ hash load_hcode;; DO hv1 <~ hash trap;; @@ -287,15 +429,59 @@ Definition hSload (hsm: hsmem) (trap: trapping_mode) (chunk: memory_chunk) (addr DO hv <~ hSload_hcodes hsm trap chunk addr lhsv;; hC_hsval {| hdata := HSload hsm trap chunk addr lhsv unknown_hid; hcodes := hv |}. +Lemma hSload_correct hsm trap chunk addr lhsv: + WHEN hSload hsm trap chunk addr lhsv ~> hv THEN forall ge sp rs0 m0 lsv sm, + list_sval_refines ge sp rs0 m0 lhsv lsv -> + smem_refines ge sp rs0 m0 hsm sm -> + sval_refines ge sp rs0 m0 hv (Sload sm trap chunk addr lsv). +Proof. + wlp_simplify. + rewrite <- H0, <- H1. + auto. +Qed. +Global Opaque hSload. +Local Hint Resolve hSload_correct: wlp. + Definition hSnil (_: unit): ?? list_hsval := hC_list_hsval {| hdata := HSnil unknown_hid; hcodes := nil |}. +Lemma hSnil_correct x: + WHEN hSnil x ~> hv THEN forall ge sp rs0 m0, + list_sval_refines ge sp rs0 m0 hv Snil. +Proof. + wlp_simplify. +Qed. +Global Opaque hSnil. +Local Hint Resolve hSnil_correct: wlp. + Definition hScons (hsv: hsval) (lhsv: list_hsval): ?? list_hsval := hC_list_hsval {| hdata := HScons hsv lhsv unknown_hid; hcodes := [hsval_get_hid hsv; list_hsval_get_hid lhsv] |}. +Lemma hScons_correct hsv lhsv: + WHEN hScons hsv lhsv ~> lhsv' THEN forall ge sp rs0 m0 sv lsv, + sval_refines ge sp rs0 m0 hsv sv -> + list_sval_refines ge sp rs0 m0 lhsv lsv -> + list_sval_refines ge sp rs0 m0 lhsv' (Scons sv lsv). +Proof. + wlp_simplify. + rewrite <- H0, <- H1. + auto. +Qed. +Global Opaque hScons. +Local Hint Resolve hScons_correct: wlp. + Definition hSinit (_: unit): ?? hsmem := hC_hsmem {| hdata := HSinit unknown_hid; hcodes := nil |}. +Lemma hSinit_correct x: + WHEN hSinit x ~> hm THEN forall ge sp rs0 m0, + smem_refines ge sp rs0 m0 hm Sinit. +Proof. + wlp_simplify. +Qed. +Global Opaque hSinit. +Local Hint Resolve hSinit_correct: wlp. + Definition hSstore_hcodes (hsm: hsmem) (chunk: memory_chunk) (addr: addressing) (lhsv: list_hsval) (srce: hsval):= DO hv1 <~ hash chunk;; DO hv2 <~ hash addr;; @@ -306,6 +492,19 @@ Definition hSstore (hsm: hsmem) (chunk: memory_chunk) (addr: addressing) (lhsv: DO hv <~ hSstore_hcodes hsm chunk addr lhsv srce;; hC_hsmem {| hdata := HSstore hsm chunk addr lhsv srce unknown_hid; hcodes := hv |}. +Lemma hSstore_correct hsm chunk addr lhsv hsv: + WHEN hSstore hsm chunk addr lhsv hsv ~> hsm' THEN forall ge sp rs0 m0 lsv sm sv, + list_sval_refines ge sp rs0 m0 lhsv lsv -> + smem_refines ge sp rs0 m0 hsm sm -> + sval_refines ge sp rs0 m0 hsv sv -> + smem_refines ge sp rs0 m0 hsm' (Sstore sm chunk addr lsv sv). +Proof. + wlp_simplify. + rewrite <- H0, <- H1, <- H2. + auto. +Qed. +Global Opaque hSstore. +Local Hint Resolve hSstore_correct: wlp. Definition hsi_sreg_get (hst: PTree.t hsval) r: ?? hsval := match PTree.get r hst with @@ -313,6 +512,18 @@ Definition hsi_sreg_get (hst: PTree.t hsval) r: ?? hsval := | Some sv => RET sv end. +Lemma hsi_sreg_get_correct hst r: + WHEN hsi_sreg_get hst r ~> hsv THEN forall ge sp rs0 m0 (f: reg -> sval), + (forall r, hsi_sreg_eval ge sp hst r rs0 m0 = seval_sval ge sp (f r) rs0 m0) -> + sval_refines ge sp rs0 m0 hsv (f r). +Proof. + unfold hsi_sreg_eval; wlp_simplify. + + rewrite <- H0, H. auto. + + rewrite <- H1, H. auto. +Qed. +Global Opaque hsi_sreg_get. +Local Hint Resolve hsi_sreg_get_correct: wlp. + Fixpoint hlist_args (hst: PTree.t hsval) (l: list reg): ?? list_hsval := match l with | nil => hSnil() @@ -322,22 +533,96 @@ Fixpoint hlist_args (hst: PTree.t hsval) (l: list reg): ?? list_hsval := hScons v lhsv end. +Lemma hlist_args_correct hst l: + WHEN hlist_args hst l ~> lhsv THEN forall ge sp rs0 m0 (f: reg -> sval), + (forall r, hsi_sreg_eval ge sp hst r rs0 m0 = seval_sval ge sp (f r) rs0 m0) -> + list_sval_refines ge sp rs0 m0 lhsv (list_sval_inj (List.map f l)). +Proof. + induction l; wlp_simplify. +Qed. +Global Opaque hlist_args. +Local Hint Resolve hlist_args_correct: wlp. + + (** ** Assignment of memory *) +Definition hslocal_set_smem (hst:hsistate_local) hm := + {| hsi_smem := hm; + hsi_ok_lsval := hsi_ok_lsval hst; + hsi_sreg:= hsi_sreg hst + |}. + +Lemma sok_local_set_mem ge sp rs0 m0 st sm: + sok_local ge sp rs0 m0 (slocal_set_smem st sm) + <-> (sok_local ge sp rs0 m0 st /\ seval_smem ge sp sm rs0 m0 <> None). +Proof. + unfold slocal_set_smem, sok_local; simpl; intuition (subst; eauto). +Qed. + +Lemma hsok_local_set_mem ge sp rs0 m0 hst hsm: + (seval_hsmem ge sp (hsi_smem hst) rs0 m0 = None -> seval_hsmem ge sp hsm rs0 m0 = None) -> + hsok_local ge sp rs0 m0 (hslocal_set_smem hst hsm) + <-> (hsok_local ge sp rs0 m0 hst /\ seval_hsmem ge sp hsm rs0 m0 <> None). +Proof. + unfold hslocal_set_smem, hsok_local; simpl; intuition. +Qed. + +Lemma hslocal_set_mem_correct ge sp rs0 m0 hst st hsm sm: + (seval_hsmem ge sp (hsi_smem hst) rs0 m0 = None -> seval_hsmem ge sp hsm rs0 m0 = None) -> + hsilocal_refines ge sp rs0 m0 hst st -> + (hsok_local ge sp rs0 m0 hst -> smem_refines ge sp rs0 m0 hsm sm) -> + hsilocal_refines ge sp rs0 m0 (hslocal_set_smem hst hsm) (slocal_set_smem st sm). +Proof. + intros PRESERV (OKEQ & SMEMEQ' & REGEQ) SMEMEQ. + split; rewrite! hsok_local_set_mem; eauto; try tauto. + rewrite sok_local_set_mem. + intuition congruence. +Qed. +Local Hint Resolve hslocal_set_mem_correct: wlp. + Definition hslocal_store (hst: hsistate_local) chunk addr args src: ?? hsistate_local := let pt := hst.(hsi_sreg) in DO hargs <~ hlist_args pt args;; DO hsrc <~ hsi_sreg_get pt src;; DO hm <~ hSstore hst chunk addr hargs hsrc;; - RET {| hsi_smem := hm; - hsi_ok_lsval := hsi_ok_lsval hst; - hsi_sreg:= hsi_sreg hst - |}. + RET (hslocal_set_smem hst hm). + +Lemma hslocal_store_correct hst chunk addr args src: + WHEN hslocal_store hst chunk addr args src ~> hst' THEN forall ge sp rs0 m0 st, + hsilocal_refines ge sp rs0 m0 hst st -> + hsilocal_refines ge sp rs0 m0 hst' (slocal_store st chunk addr args src). +Proof. + wlp_simplify. + eapply hslocal_set_mem_correct; simpl; eauto. + + intros X; erewrite H1; eauto. + rewrite X. simplify_SOME z. + + unfold hsilocal_refines in * |-; intuition eauto. +Qed. +Global Opaque hslocal_store. +Local Hint Resolve hslocal_store_correct: wlp. (** ** Assignment of local state *) Definition hsist_set_local (hst: hsistate) (pc: node) (hnxt: hsistate_local): hsistate := {| hsi_pc := pc; hsi_exits := hst.(hsi_exits); hsi_local:= hnxt |}. +Lemma hsist_set_local_correct_stat hst st pc hnxt nxt: + hsistate_refines_stat hst st -> + hsistate_refines_stat (hsist_set_local hst pc hnxt) (sist_set_local st pc nxt). +Proof. + unfold hsistate_refines_stat; simpl; intuition. +Qed. + +Lemma hsist_set_local_correct_dyn ge sp rs0 m0 hst st pc hnxt nxt: + hsistate_refines_dyn ge sp rs0 m0 hst st -> + hsilocal_refines ge sp rs0 m0 hnxt nxt -> + (sok_local ge sp rs0 m0 nxt -> sok_local ge sp rs0 m0 (si_local st)) -> + hsistate_refines_dyn ge sp rs0 m0 (hsist_set_local hst pc hnxt) (sist_set_local st pc nxt). +Proof. + unfold hsistate_refines_dyn; simpl. + intros (EREF & LREF & NESTED) LREFN SOK; intuition. + destruct NESTED as [|st0 se lse TOP NEST]; econstructor; simpl; auto. +Qed. + (** ** Assignment of registers *) (** locally new symbolic values during symbolic execution *) @@ -346,10 +631,15 @@ Inductive root_sval: Type := | Rload (trap: trapping_mode) (chunk: memory_chunk) (addr: addressing) . +Definition hSop_hSinit (op:operation) (lhsv: list_hsval): ?? hsval := + DO hsi <~ hSinit ();; + hSop op lhsv hsi (** magically remove the dependency on sm ! *) + . + Definition root_apply (rsv: root_sval) (lr: list reg) (hst: hsistate_local) : ?? hsval := DO lhsv <~ hlist_args hst lr;; match rsv with - | Rop op => hSop op lhsv hst + | Rop op => hSop_hSinit op lhsv | Rload trap chunk addr => hSload hst trap chunk addr lhsv end. @@ -363,6 +653,23 @@ Definition may_trap (rsv: root_sval) (lr: list reg): bool := | _ => false end. +Lemma lazy_orb_negb_false (b1 b2:bool): + (b1 ||| negb b2) = false <-> (b1 = false /\ b2 = true). +Proof. + unfold negb; explore; simpl; intuition (try congruence). +Qed. + +Lemma seval_list_sval_length ge sp rs0 m0 l: + forall l', seval_list_sval ge sp (list_sval_inj l) rs0 m0 = Some l' -> + Datatypes.length l = Datatypes.length l'. +Proof. + induction l. + - simpl. intros. inv H. reflexivity. + - simpl. intros. destruct (seval_sval _ _ _ _ _); [|discriminate]. + destruct (seval_list_sval _ _ _ _ _) eqn:SLS; [|discriminate]. inv H. simpl. + erewrite IHl; eauto. +Qed. + (** simplify a symbolic value before assignment to a register *) Definition simplify (rsv: root_sval) (lr: list reg) (hst: hsistate_local): ?? hsval := match rsv with @@ -370,9 +677,8 @@ Definition simplify (rsv: root_sval) (lr: list reg) (hst: hsistate_local): ?? hs match is_move_operation op lr with | Some arg => hsi_sreg_get hst arg (** optimization of Omove *) | None => - DO hsi <~ hSinit ();; DO lhsv <~ hlist_args hst lr;; - hSop op lhsv hsi (** magically remove the dependency on sm ! *) + hSop_hSinit op lhsv end | Rload _ chunk addr => DO lhsv <~ hlist_args hst lr;; @@ -391,7 +697,9 @@ Definition red_PTree_set (r: reg) (hsv: hsval) (hst: PTree.t hsval): PTree.t hsv Definition hslocal_set_sreg (hst: hsistate_local) (r: reg) (rsv: root_sval) (lr: list reg): ?? hsistate_local := DO ok_lhsv <~ (if may_trap rsv lr - then DO hv <~ root_apply rsv lr hst;; RET (hv::(hsi_ok_lsval hst)) + then DO hv <~ root_apply rsv lr hst;; + XDEBUG hv (fun hv => DO hv_name <~ string_of_hashcode (hsval_get_hid hv);; RET ("-- insert undef behavior of hashcode:" +; (CamlStr hv_name))%string);; + RET (hv::(hsi_ok_lsval hst)) else RET (hsi_ok_lsval hst));; DO simp <~ simplify rsv lr hst;; RET {| hsi_smem := hst; @@ -431,7 +739,9 @@ Fixpoint hsiexec_path (path:nat) (f: function) (hst: hsistate): ?? hsistate := match path with | O => RET hst | S p => - DO i <~ some_or_fail ((fn_code f)!(hst.(hsi_pc))) "hsiexec_path.internal_error.1";; + let pc := hst.(hsi_pc) in + XDEBUG pc (fun pc => DO name_pc <~ string_of_Z (Zpos pc);; RET ("- sym exec node: " +; name_pc)%string);; + DO i <~ some_or_fail ((fn_code f)!pc) "hsiexec_path.internal_error.1";; DO ohst1 <~ hsiexec_inst i hst;; DO hst1 <~ some_or_fail ohst1 "hsiexec_path.internal_error.2";; hsiexec_path p f hst1 @@ -475,6 +785,51 @@ Definition hsum_left (hst: PTree.t hsval) (ros: reg + ident): ?? (hsval + ident) | inr s => RET (inr s) end. +Definition hsexec_final (i: instruction) (hst: PTree.t hsval): ?? hsfval := + match i with + | Icall sig ros args res pc => + DO svos <~ hsum_left hst ros;; + DO sargs <~ hlist_args hst args;; + RET (HScall sig svos sargs res pc) + | Itailcall sig ros args => + DO svos <~ hsum_left hst ros;; + DO sargs <~ hlist_args hst args;; + RET (HStailcall sig svos sargs) + | Ibuiltin ef args res pc => + DO sargs <~ hbuiltin_args hst args;; + RET (HSbuiltin ef sargs res pc) + | Ijumptable reg tbl => + DO sv <~ hsi_sreg_get hst reg;; + RET (HSjumptable sv tbl) + | Ireturn or => + match or with + | Some r => DO hr <~ hsi_sreg_get hst r;; RET (HSreturn (Some hr)) + | None => RET (HSreturn None) + end + | _ => RET (HSnone) + end. + +Definition init_hsistate_local (_:unit): ?? hsistate_local + := DO hm <~ hSinit ();; + RET {| hsi_smem := hm; hsi_ok_lsval := nil; hsi_sreg := PTree.empty hsval |}. + +Definition init_hsistate pc: ?? hsistate + := DO hst <~ init_hsistate_local ();; + RET {| hsi_pc := pc; hsi_exits := nil; hsi_local := hst |}. + +Definition hsexec (f: function) (pc:node): ?? hsstate := + DO path <~ some_or_fail ((fn_path f)!pc) "hsexec.internal_error.1";; + DO hinit <~ init_hsistate pc;; + DO hst <~ hsiexec_path path.(psize) f hinit;; + DO i <~ some_or_fail ((fn_code f)!(hst.(hsi_pc))) "hsexec.internal_error.2";; + DO ohst <~ hsiexec_inst i hst;; + match ohst with + | Some hst' => RET {| hinternal := hst'; hfinal := HSnone |} + | None => DO hsvf <~ hsexec_final i hst.(hsi_local);; + RET {| hinternal := hst; hfinal := hsvf |} + end. + +End CanonBuilding. (** * The simulation test of concrete hash-consed symbolic execution *) @@ -483,15 +838,6 @@ Definition phys_check {A} (x y:A) (msg: pstring): ?? unit := assert_b b msg;; RET tt. -Lemma phys_check_correct {A} (a b: A) msg: - WHEN phys_check a b msg ~> tt THEN - a = b. -Proof. - wlp_simplify. -Qed. -Global Opaque phys_check. -Hint Resolve phys_check_correct: wlp. - Definition struct_check {A} (x y: A) (msg: pstring): ?? unit := DO b <~ struct_eq x y;; assert_b b msg;; @@ -513,7 +859,7 @@ Definition option_eq_check {A} (o1 o2: option A): ?? unit := Lemma option_eq_check_correct A (o1 o2: option A): WHEN option_eq_check o1 o2 ~> _ THEN o1=o2. Proof. - wlp_simplify. congruence. + wlp_simplify. Qed. Global Opaque option_eq_check. Hint Resolve option_eq_check_correct:wlp. @@ -554,383 +900,23 @@ Proof. Qed. Global Opaque PTree_frame_eq_check. -(** hsilocal_simu_check and properties *) - -Definition seval_hsval ge sp hsv rs0 m0 := seval_sval ge sp (hsval_proj hsv) rs0 m0. -Definition seval_hsmem ge sp hsm rs0 m0 := seval_smem ge sp (hsmem_proj hsm) rs0 m0. - -Definition hsi_sreg_eval ge sp (hst: PTree.t hsval) r rs0 m0: option val := - match PTree.get r hst with - | None => Some (Regmap.get r rs0) - | Some hsv => seval_hsval ge sp hsv rs0 m0 - end. - -Lemma hsi_sreg_eval_correct ge sp hst r rs0 m0: - WHEN hsi_sreg_get hst r ~> hv THEN - hsi_sreg_eval ge sp hst r rs0 m0 = seval_hsval ge sp hv rs0 m0. -Proof. - wlp_simplify. - - unfold hsi_sreg_eval. rewrite H. reflexivity. - - unfold hsi_sreg_eval. rewrite H. eapply hC_hsval_correct in Hexta1. - simpl in Hexta1. unfold seval_hsval. rewrite <- Hexta1. simpl. reflexivity. -Qed. -Hint Resolve hsi_sreg_eval_correct: wlp. - -Definition hsok_local ge sp rs0 m0 (hst: hsistate_local) : Prop := - (forall hsv, List.In hsv (hsi_ok_lsval hst) -> seval_hsval ge sp hsv rs0 m0 <> None). - -(* refinement link between a (st: sistate_local) and (hst: hsistate_local) *) -Definition hsilocal_refines ge sp rs0 m0 (hst: hsistate_local) (st: sistate_local) := - (sok_local ge sp rs0 m0 st <-> hsok_local ge sp rs0 m0 hst) - /\ (hsok_local ge sp rs0 m0 hst -> seval_hsmem ge sp (hsi_smem hst) rs0 m0 = seval_smem ge sp st.(si_smem) rs0 m0) - /\ (hsok_local ge sp rs0 m0 hst -> forall r, hsi_sreg_eval ge sp hst r rs0 m0 = seval_sval ge sp (si_sreg st r) rs0 m0) - /\ (forall r sv, hst ! r = Some sv -> In sv (hsi_ok_lsval hst)). - -Lemma ssem_local_sok ge sp rs0 m0 st rs m: - ssem_local ge sp st rs0 m0 rs m -> sok_local ge sp rs0 m0 st. -Proof. - unfold sok_local, ssem_local. - intuition congruence. -Qed. - -Lemma ssem_local_refines_hok ge sp rs0 m0 hst st rs m: - ssem_local ge sp st rs0 m0 rs m -> hsilocal_refines ge sp rs0 m0 hst st -> hsok_local ge sp rs0 m0 hst. -Proof. - intros H0 (H1 & _ & _). apply H1. eapply ssem_local_sok. eauto. -Qed. - -Definition hsilocal_simu_core (oalive: option Regset.t) (hst1 hst2: hsistate_local) := - incl (hsi_ok_lsval hst2) (hsi_ok_lsval hst1) - /\ (forall r, (match oalive with Some alive => Regset.In r alive | _ => True end) -> (* hsi_sreg_get hst2 r = hsi_sreg_get hst1 r *) - PTree.get r hst2 = PTree.get r hst1) - /\ hsi_smem hst1 = hsi_smem hst2. - -Lemma hseval_preserved ge ge' rs0 m0 sp hsv: - (forall s, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> - seval_hsval ge sp hsv rs0 m0 = seval_hsval ge' sp hsv rs0 m0. -Proof. - intros. unfold seval_hsval. erewrite seval_preserved; eauto. -Qed. - -Lemma hsmem_eval_preserved ge ge' rs0 m0 sp hsm: - (forall s, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> - seval_hsmem ge sp hsm rs0 m0 = seval_hsmem ge' sp hsm rs0 m0. -Proof. - intros. unfold seval_hsmem. erewrite smem_eval_preserved; eauto. -Qed. - -Lemma hsilocal_simu_core_nofail ge1 ge2 of sp rs0 m0 hst1 hst2: - hsilocal_simu_core of hst1 hst2 -> - (forall s, Genv.find_symbol ge1 s = Genv.find_symbol ge2 s) -> - hsok_local ge1 sp rs0 m0 hst1 -> - hsok_local ge2 sp rs0 m0 hst2. -Proof. - intros (RSOK & _ & _) GFS OKV. - intros sv INS. apply RSOK in INS. apply OKV in INS. erewrite hseval_preserved; eauto. -Qed. - -Remark istate_simulive_reflexive dm is: istate_simulive (fun _ : Regset.elt => True) dm is is. -Proof. - unfold istate_simulive. - repeat (constructor; auto). -Qed. - -Definition seval_sval_partial ge sp rs0 m0 hsv := - match seval_hsval ge sp hsv rs0 m0 with - | Some v => v - | None => Vundef - end. - -Definition select_first (ox oy: option val) := - match ox with - | Some v => Some v - | None => oy - end. - -(** If the register was computed by hrs, evaluate the symbolic value from hrs. - Else, take the value directly from rs0 *) -Definition seval_partial_regset ge sp rs0 m0 hrs := - let hrs_eval := PTree.map1 (seval_sval_partial ge sp rs0 m0) hrs in - (fst rs0, PTree.combine select_first hrs_eval (snd rs0)). - -Lemma seval_partial_regset_get ge sp rs0 m0 hrs r: - (seval_partial_regset ge sp rs0 m0 hrs) # r = - match (hrs ! r) with Some sv => seval_sval_partial ge sp rs0 m0 sv | None => (rs0 # r) end. -Proof. - unfold seval_partial_regset. unfold Regmap.get. simpl. - rewrite PTree.gcombine; [| simpl; reflexivity]. rewrite PTree.gmap1. - destruct (hrs ! r); simpl; [reflexivity|]. - destruct ((snd rs0) ! r); reflexivity. -Qed. - -Theorem hsilocal_simu_core_correct hst1 hst2 of ge1 ge2 sp rs0 m0 rs m st1 st2: - hsilocal_simu_core of hst1 hst2 -> - hsilocal_refines ge1 sp rs0 m0 hst1 st1 -> - hsilocal_refines ge2 sp rs0 m0 hst2 st2 -> - (forall s, Genv.find_symbol ge1 s = Genv.find_symbol ge2 s) -> - ssem_local ge1 sp st1 rs0 m0 rs m -> - match of with - | None => ssem_local ge2 sp st2 rs0 m0 rs m - | Some alive => - let rs' := seval_partial_regset ge2 sp rs0 m0 (hsi_sreg hst2) - in ssem_local ge2 sp st2 rs0 m0 rs' m /\ eqlive_reg (fun r => Regset.In r alive) rs rs' - end. -Proof. - intros CORE HREF1 HREF2 GFS SEML. - refine (modusponens _ _ (ssem_local_refines_hok _ _ _ _ _ _ _ _ _ _) _); eauto. - intro HOK1. - refine (modusponens _ _ (hsilocal_simu_core_nofail _ _ _ _ _ _ _ _ _ _ _) _); eauto. - intro HOK2. - destruct SEML as (PRE & MEMEQ & RSEQ). - assert (SIPRE: si_pre st2 ge2 sp rs0 m0). { destruct HREF2 as (OKEQ & _ & _). rewrite <- OKEQ in HOK2. apply HOK2. } - assert (SMEMEVAL: seval_smem ge2 sp (si_smem st2) rs0 m0 = Some m). { - destruct HREF2 as (_ & MEMEQ2 & _). destruct HREF1 as (_ & MEMEQ1 & _). - destruct CORE as (_ & _ & MEMEQ3). - rewrite <- MEMEQ2; auto. rewrite <- MEMEQ3. - erewrite hsmem_eval_preserved; [| eapply GFS]. - rewrite MEMEQ1; auto. } - destruct of as [alive |]. - - constructor. - + constructor; [assumption | constructor; [assumption|]]. - destruct HREF2 as (B & _ & A & PT). - (** B, A and PT are used for the auto below *) - assert (forall r : positive, hsi_sreg_eval ge2 sp hst2 r rs0 m0 = seval_sval ge2 sp (si_sreg st2 r) rs0 m0) by auto. - intro r. rewrite <- H. clear H. rewrite seval_partial_regset_get. unfold hsi_sreg_eval. - destruct (hst2 ! r) eqn:HST2; [| simpl; reflexivity]. - unfold seval_sval_partial. - assert (seval_hsval ge2 sp h rs0 m0 <> None) by eauto. - destruct (seval_hsval ge2 sp h rs0 m0); [reflexivity | contradiction]. - + intros r ALIVE. destruct HREF2 as (_ & _ & A & _). destruct HREF1 as (_ & _ & B & _). - destruct CORE as (_ & C & _). rewrite seval_partial_regset_get. - assert (OPT: forall (x y: val), Some x = Some y -> x = y) by congruence. - destruct (hst2 ! r) eqn:HST2; apply OPT; clear OPT. - ++ unfold seval_sval_partial. - assert (seval_hsval ge2 sp h rs0 m0 = hsi_sreg_eval ge2 sp hst2 r rs0 m0). { - unfold hsi_sreg_eval. rewrite HST2. reflexivity. } - rewrite H. clear H. - unfold hsi_sreg_eval. rewrite HST2. - erewrite hseval_preserved; [| eapply GFS]. - unfold hsi_sreg_eval in B. - generalize (B HOK1 r); clear B; intro B. - rewrite <- C in B; eauto. - rewrite HST2 in B. - rewrite B, RSEQ. - reflexivity. - ++ rewrite <- RSEQ. rewrite <- B; [|assumption]. - unfold hsi_sreg_eval. rewrite <- C; [|assumption]. rewrite HST2. reflexivity. - - constructor; [|constructor]. - + destruct HREF2 as (OKEQ & _ & _). rewrite <- OKEQ in HOK2. apply HOK2. - + destruct HREF2 as (_ & MEMEQ2 & _). destruct HREF1 as (_ & MEMEQ1 & _). - destruct CORE as (_ & _ & MEMEQ3). - rewrite <- MEMEQ2; auto. rewrite <- MEMEQ3. erewrite hsmem_eval_preserved; [| eapply GFS]. - rewrite MEMEQ1; auto. - + intro r. destruct HREF2 as (_ & _ & A & _). destruct HREF1 as (_ & _ & B & _). - destruct CORE as (_ & C & _). rewrite <- A; auto. - unfold hsi_sreg_eval. destruct (hst2 ! r) eqn:HST2. - ++ assert (seval_hsval ge2 sp h rs0 m0 = hsi_sreg_eval ge2 sp hst2 r rs0 m0). { - unfold hsi_sreg_eval. rewrite HST2. reflexivity. } - rewrite H. clear H. - unfold hsi_sreg_eval. rewrite HST2. - erewrite hseval_preserved; [| eapply GFS]. - unfold hsi_sreg_eval in B. - generalize (B HOK1 r); clear B; intro B. - rewrite <- C in B; eauto. rewrite HST2 in B. rewrite B, RSEQ. reflexivity. - ++ rewrite <- RSEQ. rewrite <- B; [|assumption]. - unfold hsi_sreg_eval. rewrite <- C; [|auto]. rewrite HST2. reflexivity. -Qed. - Definition hsilocal_simu_check hst1 hst2 : ?? unit := + DEBUG("? last check");; phys_check (hsi_smem hst2) (hsi_smem hst1) "hsilocal_simu_check: hsi_smem sets aren't equiv";; + PTree_eq_check (hsi_sreg hst1) (hsi_sreg hst2);; Sets.assert_list_incl mk_hash_params (hsi_ok_lsval hst2) (hsi_ok_lsval hst1);; - PTree_eq_check (hsi_sreg hst1) (hsi_sreg hst2). - -Theorem hsilocal_simu_check_correct hst1 hst2: - WHEN hsilocal_simu_check hst1 hst2 ~> tt THEN - hsilocal_simu_core None hst1 hst2. -Proof. - wlp_simplify. constructor; [|constructor]; [assumption | | congruence]. - intros. unfold hsi_sreg_get. rewrite (PTree_eq_check_correct _ hst1 hst2); [|eassumption]. - reflexivity. -Qed. -Hint Resolve hsilocal_simu_check_correct: wlp. -Global Opaque hsilocal_simu_check. - -Definition hsilocal_frame_simu_check frame hst1 hst2 : ?? unit := - phys_check (hsi_smem hst2) (hsi_smem hst1) "hsilocal_frame_simu_check: hsi_smem sets aren't equiv";; - Sets.assert_list_incl mk_hash_params (hsi_ok_lsval hst2) (hsi_ok_lsval hst1);; - PTree_frame_eq_check frame (hsi_sreg hst1) (hsi_sreg hst2). - -Lemma setoid_in {A: Type} (a: A): forall l, - SetoidList.InA (fun x y => x = y) a l -> - In a l. -Proof. - induction l; intros; inv H. - - constructor. reflexivity. - - right. auto. -Qed. - -Lemma regset_elements_in r rs: - Regset.In r rs -> - In r (Regset.elements rs). -Proof. - intros. exploit Regset.elements_1; eauto. intro SIN. - apply setoid_in. assumption. -Qed. - -Local Hint Resolve PTree_frame_eq_check_correct: wlp. -Local Hint Resolve regset_elements_in: core. - -Theorem hsilocal_frame_simu_check_correct hst1 hst2 alive: - WHEN hsilocal_frame_simu_check (Regset.elements alive) hst1 hst2 ~> tt THEN - hsilocal_simu_core (Some alive) hst1 hst2. -Proof. - wlp_simplify. constructor; [|constructor]; [assumption | | congruence]. - intros. symmetry. eauto. -(* rewrite (PTree_frame_eq_check_correct _ (Regset.elements alive) hst1 hst2); [reflexivity | eassumption | ]. - apply regset_elements_in. assumption. *) -Qed. -Hint Resolve hsilocal_frame_simu_check_correct: wlp. -Global Opaque hsilocal_frame_simu_check. - -Definition init_hsistate_local (_:unit): ?? hsistate_local - := DO hm <~ hSinit ();; - RET {| hsi_smem := hm; hsi_ok_lsval := nil; hsi_sreg := PTree.empty hsval |}. - -Remark hsinit_seval_hsmem ge sp rs0 m0: - WHEN hSinit () ~> init THEN - seval_hsmem ge sp init rs0 m0 = Some m0. -Proof. - wlp_simplify. unfold hSinit in Hexta. apply hC_hsmem_correct in Hexta. simpl in Hexta. - unfold seval_hsmem. rewrite <- Hexta. simpl. reflexivity. -Qed. - -Remark init_hsistate_local_correct ge sp rs0 m0: - WHEN init_hsistate_local () ~> hsl THEN - hsilocal_refines ge sp rs0 m0 hsl init_sistate_local. -Proof. - wlp_simplify. - constructor; constructor; simpl. - - intro. destruct H as (_ & SMEM & SVAL). unfold hsok_local. simpl. contradiction. - - intro. constructor; [simpl; auto|]. constructor; simpl; discriminate. - - unfold hsok_local. simpl. intros; simpl. apply hsinit_seval_hsmem. assumption. - - constructor. - + intros. simpl. unfold hsi_sreg_eval. rewrite PTree.gempty. reflexivity. - + intros r sv. rewrite PTree.gempty. discriminate. -Qed. - -(** Simulation of exits *) - -Definition hsiexit_simu_core dm f (hse1 hse2: hsistate_exit) := - (exists path, (fn_path f) ! (hsi_ifso hse1) = Some path - /\ hsilocal_simu_core (Some path.(input_regs)) (hsi_elocal hse1) (hsi_elocal hse2)) - /\ dm ! (hsi_ifso hse2) = Some (hsi_ifso hse1) - /\ hsi_cond hse1 = hsi_cond hse2 - /\ hsi_scondargs hse1 = hsi_scondargs hse2 (* FIXME - should there be something about okvals ? *). - -(** NB: we split the refinement relation between a "static" part -- independendent of the initial context - and a "dynamic" part -- that depends on it -*) -Definition hsiexit_refines_stat (hext: hsistate_exit) (ext: sistate_exit): Prop := - hsi_ifso hext = si_ifso ext. - -Definition hsok_exit ge sp rs m hse := hsok_local ge sp rs m (hsi_elocal hse). - -Definition hseval_condition ge sp cond hcondargs hmem rs0 m0 := - seval_condition ge sp cond (hsval_list_proj hcondargs) (hsmem_proj hmem) rs0 m0. - -Lemma hseval_condition_preserved ge ge' sp cond args mem rs0 m0: - (forall s : ident, Genv.find_symbol ge' s = Genv.find_symbol ge s) -> - hseval_condition ge sp cond args mem rs0 m0 = hseval_condition ge' sp cond args mem rs0 m0. -Proof. - intros. unfold hseval_condition. erewrite seval_condition_preserved; [|eapply H]. - reflexivity. -Qed. - -Definition hsiexit_refines_dyn ge sp rs0 m0 (hext: hsistate_exit) (ext: sistate_exit): Prop := - hsilocal_refines ge sp rs0 m0 (hsi_elocal hext) (si_elocal ext) - /\ (hsok_local ge sp rs0 m0 (hsi_elocal hext) -> - hseval_condition ge sp (hsi_cond hext) (hsi_scondargs hext) (hsi_smem (hsi_elocal hext)) rs0 m0 - = seval_condition ge sp (si_cond ext) (si_scondargs ext) (si_smem (si_elocal ext)) rs0 m0). - -Definition hsiexit_simu dm f (ctx: simu_proof_context f) hse1 hse2: Prop := forall se1 se2, - hsiexit_refines_stat hse1 se1 -> - hsiexit_refines_stat hse2 se2 -> - hsiexit_refines_dyn (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse1 se1 -> - hsiexit_refines_dyn (the_ge2 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse2 se2 -> - siexit_simu dm f ctx se1 se2. - -Lemma hsiexit_simu_core_nofail dm f hse1 hse2 ge1 ge2 sp rs m: - hsiexit_simu_core dm f hse1 hse2 -> - (forall s, Genv.find_symbol ge1 s = Genv.find_symbol ge2 s) -> - hsok_exit ge1 sp rs m hse1 -> - hsok_exit ge2 sp rs m hse2. -Proof. - intros CORE GFS HOK1. - destruct CORE as ((p & _ & CORE') & _ & _ & _). - eapply hsilocal_simu_core_nofail; eauto. -Qed. - -Theorem hsiexit_simu_core_correct dm f hse1 hse2 ctx: - hsiexit_simu_core dm f hse1 hse2 -> - hsiexit_simu dm f ctx hse1 hse2. -Proof. - intros SIMUC st1 st2 HREF1 HREF2 HDYN1 HDYN2. - assert (SEVALC: - sok_local (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) (si_elocal st1) -> - (seval_condition (the_ge1 ctx) (the_sp ctx) (si_cond st1) (si_scondargs st1) (si_smem (si_elocal st1)) - (the_rs0 ctx) (the_m0 ctx)) = - (seval_condition (the_ge2 ctx) (the_sp ctx) (si_cond st2) (si_scondargs st2) (si_smem (si_elocal st2)) - (the_rs0 ctx) (the_m0 ctx))). - { destruct HDYN1 as ((OKEQ1 & _) & SCOND1). - rewrite OKEQ1; intro OK1. rewrite <- SCOND1 by assumption. clear SCOND1. - generalize (genv_match ctx). - intro GFS; refine (modusponens _ _ (hsiexit_simu_core_nofail _ _ _ _ _ _ _ _ _ _ _ _) _); eauto. - destruct HDYN2 as (_ & SCOND2). intro OK2. rewrite <- SCOND2 by assumption. clear OK1 OK2 SCOND2. - destruct SIMUC as ((path & _ & LSIMU) & _ & CONDEQ & ARGSEQ). destruct LSIMU as (_ & _ & MEMEQ). - rewrite CONDEQ. rewrite ARGSEQ. rewrite MEMEQ. erewrite <- hseval_condition_preserved; eauto. - } - constructor; [assumption|]. intros is1 ICONT SSEME. - assert (OK1: sok_local (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) (si_elocal st1)). { - destruct SSEME as (_ & SSEML & _). eapply ssem_local_sok; eauto. } - assert (HOK1: hsok_exit (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse1). { - unfold hsok_exit. destruct HDYN1 as (LREF & _). destruct LREF as (OKEQ & _ & _). rewrite <- OKEQ. assumption. } - refine (modusponens _ _ (hsiexit_simu_core_nofail _ _ _ _ _ _ _ _ _ _ _ _) _). - 2: eapply ctx. all: eauto. intro HOK2. - destruct SSEME as (SCOND & SLOC & PCEQ). destruct SIMUC as ((path & PATH & LSIMU) & REVEQ & _ & _); eauto. - destruct HDYN1 as (LREF1 & _). destruct HDYN2 as (LREF2 & _). - exploit hsilocal_simu_core_correct; eauto; [apply ctx|]. simpl. - intros (SSEML & EQREG). - eexists (mk_istate (icontinue is1) (si_ifso st2) _ (imem is1)). simpl. constructor. - - constructor; intuition congruence || eauto. - - unfold istate_simu. rewrite ICONT. - simpl. assert (PCEQ': hsi_ifso hse1 = ipc is1) by congruence. - exists path. constructor; [|constructor]; [congruence| |congruence]. - constructor; [|constructor]; simpl; auto. -Qed. - -Remark hsiexit_simu_siexit dm f ctx hse1 hse2 se1 se2: - hsiexit_simu dm f ctx hse1 hse2 -> - hsiexit_refines_stat hse1 se1 -> - hsiexit_refines_stat hse2 se2 -> - hsiexit_refines_dyn (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse1 se1 -> - hsiexit_refines_dyn (the_ge2 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse2 se2 -> - siexit_simu dm f ctx se1 se2. -Proof. - auto. -Qed. + DEBUG("=> last check: OK"). Definition revmap_check_single (dm: PTree.t node) (n tn: node) : ?? unit := DO res <~ some_or_fail (dm ! tn) "revmap_check_single: no mapping for tn";; struct_check n res "revmap_check_single: n and res are physically different". -Lemma revmap_check_single_correct dm pc1 pc2: - WHEN revmap_check_single dm pc1 pc2 ~> tt THEN - dm ! pc2 = Some pc1. -Proof. - wlp_simplify. congruence. -Qed. -Hint Resolve revmap_check_single_correct: wlp. -Global Opaque revmap_check_single. +Definition hsilocal_frame_simu_check frame hst1 hst2 : ?? unit := + DEBUG("? frame check");; + phys_check (hsi_smem hst2) (hsi_smem hst1) "hsilocal_frame_simu_check: hsi_smem sets aren't equiv";; + PTree_frame_eq_check frame (hsi_sreg hst1) (hsi_sreg hst2);; + Sets.assert_list_incl mk_hash_params (hsi_ok_lsval hst2) (hsi_ok_lsval hst1);; + DEBUG("=> frame check: OK"). Definition hsiexit_simu_check (dm: PTree.t node) (f: RTLpath.function) (hse1 hse2: hsistate_exit): ?? unit := struct_check (hsi_cond hse1) (hsi_cond hse2) "hsiexit_simu_check: conditions do not match";; @@ -939,37 +925,6 @@ Definition hsiexit_simu_check (dm: PTree.t node) (f: RTLpath.function) (hse1 hse DO path <~ some_or_fail ((fn_path f) ! (hsi_ifso hse1)) "hsiexit_simu_check: internal error";; hsilocal_frame_simu_check (Regset.elements path.(input_regs)) (hsi_elocal hse1) (hsi_elocal hse2). -Theorem hsiexit_simu_check_correct dm f hse1 hse2: - WHEN hsiexit_simu_check dm f hse1 hse2 ~> tt THEN - hsiexit_simu_core dm f hse1 hse2. -Proof. - wlp_simplify. constructor; [| constructor; [| constructor]]. 2-4: assumption. - exists a. constructor. 1-2: assumption. -Qed. -Hint Resolve hsiexit_simu_check_correct: wlp. -Global Opaque hsiexit_simu_check. - -Definition hsiexits_simu dm f (ctx: simu_proof_context f) lhse1 lhse2: Prop := - list_forall2 (hsiexit_simu dm f ctx) lhse1 lhse2. - -Definition hsiexits_simu_core dm f lhse1 lhse2: Prop := - list_forall2 (hsiexit_simu_core dm f) lhse1 lhse2. - -Theorem hsiexits_simu_core_correct dm f lhse1 lhse2 ctx: - hsiexits_simu_core dm f lhse1 lhse2 -> - hsiexits_simu dm f ctx lhse1 lhse2. -Proof. - induction 1; [constructor|]. - constructor; [|apply IHlist_forall2; assumption]. - apply hsiexit_simu_core_correct; assumption. -Qed. - -Definition hsiexits_refines_stat lhse lse := - list_forall2 hsiexit_refines_stat lhse lse. - -Definition hsiexits_refines_dyn ge sp rs0 m0 lhse se := - list_forall2 (hsiexit_refines_dyn ge sp rs0 m0) lhse se. - Fixpoint hsiexits_simu_check (dm: PTree.t node) (f: RTLpath.function) (lhse1 lhse2: list hsistate_exit) := match lhse1,lhse2 with | nil, nil => RET tt @@ -979,718 +934,9 @@ Fixpoint hsiexits_simu_check (dm: PTree.t node) (f: RTLpath.function) (lhse1 lhs | _, _ => FAILWITH "siexists_simu_check: lengths do not match" end. -Theorem hsiexits_simu_check_correct dm f: forall le1 le2, - WHEN hsiexits_simu_check dm f le1 le2 ~> tt THEN - hsiexits_simu_core dm f le1 le2. -Proof. - induction le1; simpl. - - destruct le2; wlp_simplify. constructor. - - destruct le2; wlp_simplify. constructor; [assumption|]. - eapply IHle1. eassumption. -Qed. -Hint Resolve hsiexits_simu_check_correct: wlp. -Global Opaque hsiexits_simu_check. - -Definition hsistate_simu_core dm f (hse1 hse2: hsistate) := - dm ! (hsi_pc hse2) = Some (hsi_pc hse1) - /\ list_forall2 (hsiexit_simu_core dm f) (hsi_exits hse1) (hsi_exits hse2) - /\ hsilocal_simu_core None (hsi_local hse1) (hsi_local hse2). - -Definition hsistate_refines_stat (hst: hsistate) (st:sistate): Prop := - hsi_pc hst = si_pc st - /\ hsiexits_refines_stat (hsi_exits hst) (si_exits st). - -Inductive nested_sok ge sp rs0 m0: sistate_local -> list sistate_exit -> Prop := - nsok_nil st: nested_sok ge sp rs0 m0 st nil - | nsok_cons st se lse: - (sok_local ge sp rs0 m0 st -> sok_local ge sp rs0 m0 (si_elocal se)) -> - nested_sok ge sp rs0 m0 (si_elocal se) lse -> - nested_sok ge sp rs0 m0 st (se::lse). - -Lemma nested_sok_prop ge sp st sle rs0 m0: - nested_sok ge sp rs0 m0 st sle -> - sok_local ge sp rs0 m0 st -> - forall se, In se sle -> sok_local ge sp rs0 m0 (si_elocal se). -Proof. - induction 1; simpl; intuition (subst; eauto). -Qed. - -Lemma nested_sok_elocal ge sp rs0 m0 st2 exits: - nested_sok ge sp rs0 m0 st2 exits -> - forall st1, (sok_local ge sp rs0 m0 st1 -> sok_local ge sp rs0 m0 st2) -> - nested_sok ge sp rs0 m0 st1 exits. -Proof. - induction 1; [intros; constructor|]. - intros. constructor; auto. -Qed. - -Lemma nested_sok_tail ge sp rs0 m0 st lx exits: - is_tail lx exits -> - nested_sok ge sp rs0 m0 st exits -> - nested_sok ge sp rs0 m0 st lx. -Proof. - induction 1; [auto|]. - intros. inv H0. eapply IHis_tail. eapply nested_sok_elocal; eauto. -Qed. - -Definition hsistate_refines_dyn ge sp rs0 m0 (hst: hsistate) (st:sistate): Prop := - hsiexits_refines_dyn ge sp rs0 m0 (hsi_exits hst) (si_exits st) - /\ hsilocal_refines ge sp rs0 m0 (hsi_local hst) (si_local st) - /\ nested_sok ge sp rs0 m0 (si_local st) (si_exits st). - -Definition hsistate_simu dm f (hst1 hst2: hsistate) (ctx: simu_proof_context f): Prop := forall st1 st2, - hsistate_refines_stat hst1 st1 -> - hsistate_refines_stat hst2 st2 -> - hsistate_refines_dyn (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hst1 st1 -> - hsistate_refines_dyn (the_ge2 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hst2 st2 -> - sistate_simu dm f st1 st2 ctx. - -Definition init_hsistate pc: ?? hsistate - := DO hst <~ init_hsistate_local ();; - RET {| hsi_pc := pc; hsi_exits := nil; hsi_local := hst |}. - -Remark init_hsistate_correct_stat pc: - WHEN init_hsistate pc ~> hst THEN - hsistate_refines_stat hst (init_sistate pc). -Proof. - wlp_simplify. - constructor; constructor; simpl; auto. -Qed. -Hint Resolve init_hsistate_correct_stat: wlp. - -Remark init_hsistate_correct_dyn ge sp rs0 m0 pc: - WHEN init_hsistate pc ~> hst THEN - hsistate_refines_dyn ge sp rs0 m0 hst (init_sistate pc). -Proof. - unfold init_hsistate. wlp_bind hst. - wlp_simplify. - constructor; simpl; auto; [|constructor]. - - apply list_forall2_nil. - - apply init_hsistate_local_correct. assumption. - - constructor. -Qed. - -Lemma siexits_simu_all_fallthrough dm f ctx: forall lse1 lse2, - siexits_simu dm f lse1 lse2 ctx -> - all_fallthrough (the_ge1 ctx) (the_sp ctx) lse1 (the_rs0 ctx) (the_m0 ctx) -> - (forall se1, In se1 lse1 -> sok_local (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) (si_elocal se1)) -> - all_fallthrough (the_ge2 ctx) (the_sp ctx) lse2 (the_rs0 ctx) (the_m0 ctx). -Proof. - induction 1; [unfold all_fallthrough; contradiction|]; simpl. - intros X OK ext INEXT. eapply all_fallthrough_revcons in X. destruct X as (SEVAL & ALLFU). - apply IHlist_forall2 in ALLFU. - - destruct H as (CONDSIMU & _). - inv INEXT; [|eauto]. - erewrite <- CONDSIMU; eauto. - - intros; intuition. -Qed. - -Lemma hsiexits_simu_siexits dm f ctx lhse1 lhse2: - hsiexits_simu dm f ctx lhse1 lhse2 -> - forall lse1 lse2, - hsiexits_refines_stat lhse1 lse1 -> - hsiexits_refines_stat lhse2 lse2 -> - hsiexits_refines_dyn (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) lhse1 lse1 -> - hsiexits_refines_dyn (the_ge2 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) lhse2 lse2 -> - siexits_simu dm f lse1 lse2 ctx. -Proof. - induction 1. - - intros. inv H. inv H0. constructor. - - intros lse1 lse2 SREF1 SREF2 DREF1 DREF2. inv SREF1. inv SREF2. inv DREF1. inv DREF2. - constructor; [| eapply IHlist_forall2; eauto]. - eapply hsiexit_simu_siexit; eauto. -Qed. - -Lemma siexits_simu_all_fallthrough_upto dm f ctx lse1 lse2: - siexits_simu dm f lse1 lse2 ctx -> - forall ext1 lx1, - (forall se1, In se1 lx1 -> sok_local (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) (si_elocal se1)) -> - all_fallthrough_upto_exit (the_ge1 ctx) (the_sp ctx) ext1 lx1 lse1 (the_rs0 ctx) (the_m0 ctx) -> - exists ext2 lx2, - all_fallthrough_upto_exit (the_ge2 ctx) (the_sp ctx) ext2 lx2 lse2 (the_rs0 ctx) (the_m0 ctx) - /\ length lx1 = length lx2. -Proof. - induction 1. - - intros ext lx1. intros OK H. destruct H as (ITAIL & ALLFU). eapply is_tail_false in ITAIL. contradiction. - - simpl; intros ext lx1 OK ALLFUE. - destruct ALLFUE as (ITAIL & ALLFU). inv ITAIL. - + eexists; eexists. - constructor; [| eapply list_forall2_length; eauto]. - constructor; [econstructor | eapply siexits_simu_all_fallthrough; eauto]. - + exploit IHlist_forall2. - * intuition. apply OK. eassumption. - * constructor; eauto. - * intros (ext2 & lx2 & ALLFUE2 & LENEQ). - eexists; eexists. constructor; eauto. - eapply all_fallthrough_upto_exit_cons; eauto. -Qed. - -Lemma list_forall2_nth_error {A} (l1 l2: list A) P: - list_forall2 P l1 l2 -> - forall x1 x2 n, - nth_error l1 n = Some x1 -> - nth_error l2 n = Some x2 -> - P x1 x2. -Proof. - induction 1. - - intros. rewrite nth_error_nil in H. discriminate. - - intros x1 x2 n. destruct n as [|n]; simpl. - + intros. inv H1. inv H2. assumption. - + apply IHlist_forall2. -Qed. - -Lemma is_tail_length {A} (l1 l2: list A): - is_tail l1 l2 -> - (length l1 <= length l2)%nat. -Proof. - induction l2. - - intro. destruct l1; auto. apply is_tail_false in H. contradiction. - - intros ITAIL. inv ITAIL; auto. - apply IHl2 in H1. clear IHl2. simpl. omega. -Qed. - -Lemma is_tail_nth_error {A} (l1 l2: list A) x: - is_tail (x::l1) l2 -> - nth_error l2 ((length l2) - length l1 - 1) = Some x. -Proof. - induction l2. - - intro ITAIL. apply is_tail_false in ITAIL. contradiction. - - intros ITAIL. assert (length (a::l2) = S (length l2)) by auto. rewrite H. clear H. - assert (forall n n', ((S n) - n' - 1)%nat = (n - n')%nat) by (intros; omega). rewrite H. clear H. - inv ITAIL. - + assert (forall n, (n - n)%nat = 0%nat) by (intro; omega). rewrite H. - simpl. reflexivity. - + exploit IHl2; eauto. intros. clear IHl2. - assert (forall n n', (n > n')%nat -> (n - n')%nat = S (n - n' - 1)%nat) by (intros; omega). - exploit (is_tail_length (x::l1)); eauto. intro. simpl in H2. - assert ((length l2 > length l1)%nat) by omega. clear H2. - rewrite H0; auto. -Qed. - -Theorem hsistate_simu_core_correct dm f hst1 hst2 ctx: - hsistate_simu_core dm f hst1 hst2 -> - hsistate_simu dm f hst1 hst2 ctx. -Proof. - intros SIMUC st1 st2 HREF1 HREF2 DREF1 DREF2 is1 SEMI. - destruct HREF1 as (PCREF1 & EREF1). destruct HREF2 as (PCREF2 & EREF2). - destruct DREF1 as (DEREF1 & LREF1 & NESTED). destruct DREF2 as (DEREF2 & LREF2 & _). - destruct SIMUC as (PCSIMU & ESIMU & LSIMU). - exploit hsiexits_simu_core_correct; eauto. intro HESIMU. - unfold ssem_internal in SEMI. destruct (icontinue _) eqn:ICONT. - - destruct SEMI as (SSEML & PCEQ & ALLFU). - exploit hsilocal_simu_core_correct; eauto; [apply ctx|]. simpl. intro SSEML2. - exists (mk_istate (icontinue is1) (si_pc st2) (irs is1) (imem is1)). constructor. - + unfold ssem_internal. simpl. rewrite ICONT. constructor; [assumption | constructor; [reflexivity |]]. - eapply siexits_simu_all_fallthrough; eauto. - * eapply hsiexits_simu_siexits; eauto. - * eapply nested_sok_prop; eauto. - eapply ssem_local_sok; eauto. - + unfold istate_simu. rewrite ICONT. constructor; [simpl; assumption | constructor; [| reflexivity]]. - constructor. - - destruct SEMI as (ext & lx & SSEME & ALLFU). - assert (SESIMU: siexits_simu dm f (si_exits st1) (si_exits st2) ctx) by (eapply hsiexits_simu_siexits; eauto). - exploit siexits_simu_all_fallthrough_upto; eauto. - * destruct ALLFU as (ITAIL & ALLF). - exploit nested_sok_tail; eauto. intros NESTED2. - inv NESTED2. destruct SSEME as (_ & SSEML & _). eapply ssem_local_sok in SSEML. - eapply nested_sok_prop; eauto. - * intros (ext2 & lx2 & ALLFU2 & LENEQ). - assert (EXTSIMU: siexit_simu dm f ctx ext ext2). { - eapply list_forall2_nth_error; eauto. - - destruct ALLFU as (ITAIL & _). eapply is_tail_nth_error; eauto. - - destruct ALLFU2 as (ITAIL & _). eapply is_tail_nth_error in ITAIL. - assert (LENEQ': length (si_exits st1) = length (si_exits st2)) by (eapply list_forall2_length; eauto). - congruence. } - destruct EXTSIMU as (CONDEVAL & EXTSIMU). - apply EXTSIMU in SSEME; [|assumption]. clear EXTSIMU. destruct SSEME as (is2 & SSEME2 & ISIMU). - exists (mk_istate (icontinue is1) (ipc is2) (irs is2) (imem is2)). constructor. - + unfold ssem_internal. simpl. rewrite ICONT. exists ext2, lx2. constructor; assumption. - + unfold istate_simu in *. rewrite ICONT in *. destruct ISIMU as (path & PATHEQ & ISIMULIVE & DMEQ). - destruct ISIMULIVE as (CONTEQ & REGEQ & MEMEQ). - exists path. repeat (constructor; auto). -Qed. - Definition hsistate_simu_check (dm: PTree.t node) (f: RTLpath.function) (hst1 hst2: hsistate) := - revmap_check_single dm (hsi_pc hst1) (hsi_pc hst2);; - hsilocal_simu_check (hsi_local hst1) (hsi_local hst2);; - hsiexits_simu_check dm f (hsi_exits hst1) (hsi_exits hst2). - -Theorem hsistate_simu_check_correct dm f hst1 hst2: - WHEN hsistate_simu_check dm f hst1 hst2 ~> tt THEN - hsistate_simu_core dm f hst1 hst2. -Proof. - wlp_simplify. - constructor; [|constructor]. 1-3: assumption. -Qed. -Hint Resolve hsistate_simu_check_correct: wlp. -Global Opaque hsistate_simu_check. - -Definition hsi_proj (hsi: hsval + ident) := match hsi with - | inl hv => inl (hsval_proj hv) - | inr id => inr id - end. - -Fixpoint barg_proj (bhv: builtin_arg hsval) := match bhv with - | BA hv => BA (hsval_proj hv) - | BA_splitlong ba1 ba2 => BA_splitlong (barg_proj ba1) (barg_proj ba2) - | BA_addptr ba1 ba2 => BA_addptr (barg_proj ba1) (barg_proj ba2) - | BA_int i => BA_int i - | BA_long i => BA_long i - | BA_float f => BA_float f - | BA_single f32 => BA_single f32 - | BA_loadstack m p => BA_loadstack m p - | BA_addrstack p => BA_addrstack p - | BA_loadglobal c i p => BA_loadglobal c i p - | BA_addrglobal i p => BA_addrglobal i p - end. - -Fixpoint barg_list_proj lbh := match lbh with - | [] => [] - | bh::lbh => (barg_proj bh) :: (barg_list_proj lbh) - end. - -Definition option_hsval_proj oh := match oh with None => None | Some h => Some (hsval_proj h) end. - -Definition hfinal_proj hfv := match hfv with - | HSnone => Snone - | HScall s hvi hlv r pc => Scall s (hsi_proj hvi) (hsval_list_proj hlv) r pc - | HStailcall s hvi hlv => Stailcall s (hsi_proj hvi) (hsval_list_proj hlv) - | HSbuiltin ef lbh br pc => Sbuiltin ef (barg_list_proj lbh) br pc - | HSjumptable hv ln => Sjumptable (hsval_proj hv) ln - | HSreturn oh => Sreturn (option_hsval_proj oh) - end. - -Section HFINAL_REFINES. - -Variable ge: RTL.genv. -Variable sp: val. -Variable rs0: regset. -Variable m0: mem. - -Definition sval_refines (hv: hsval) (sv: sval) := seval_hsval ge sp hv rs0 m0 = seval_sval ge sp sv rs0 m0. - -Definition sum_refines (hsi: hsval + ident) (si: sval + ident) := - match hsi, si with - | inl hv, inl sv => sval_refines hv sv - | inr id, inr id' => id = id' - | _, _ => False - end. - -Inductive list_refines: list_hsval -> list_sval -> Prop := - | hsnil_ref: forall h, list_refines (HSnil h) Snil - | hscons_ref: forall lhv lsv hv sv h, - list_refines lhv lsv -> - sval_refines hv sv -> - list_refines (HScons hv lhv h) (Scons sv lsv). - -Inductive barg_refines: builtin_arg hsval -> builtin_arg sval -> Prop := - | hba_ref: forall hsv sv, sval_refines hsv sv -> barg_refines (BA hsv) (BA sv) - | hba_splitlong: forall bha1 bha2 ba1 ba2, - barg_refines bha1 ba1 -> barg_refines bha2 ba2 -> - barg_refines (BA_splitlong bha1 bha2) (BA_splitlong ba1 ba2) - | hba_addptr: forall bha1 bha2 ba1 ba2, - barg_refines bha1 ba1 -> barg_refines bha2 ba2 -> - barg_refines (BA_addptr bha1 bha2) (BA_addptr ba1 ba2) - | hba_int: forall i, barg_refines (BA_int i) (BA_int i) - | hba_long: forall l, barg_refines (BA_long l) (BA_long l) - | hba_float: forall f, barg_refines (BA_float f) (BA_float f) - | hba_single: forall s, barg_refines (BA_single s) (BA_single s) - | hba_loadstack: forall chk ptr, barg_refines (BA_loadstack chk ptr) (BA_loadstack chk ptr) - | hba_addrstack: forall ptr, barg_refines (BA_addrstack ptr) (BA_addrstack ptr) - | hba_loadglobal: forall chk id ptr, barg_refines (BA_loadglobal chk id ptr) (BA_loadglobal chk id ptr) - | hba_addrglobal: forall id ptr, barg_refines (BA_addrglobal id ptr) (BA_addrglobal id ptr). - -Definition option_refines ohsv osv := - match ohsv, osv with - | Some hsv, Some sv => sval_refines hsv sv - | None, None => True - | _, _ => False - end. - -Inductive hfinal_refines: hsfval -> sfval -> Prop := - | hsnone_ref: hfinal_refines HSnone Snone - | hscall_ref: forall hros ros hargs args s r pc, - sum_refines hros ros -> - list_refines hargs args -> - hfinal_refines (HScall s hros hargs r pc) (Scall s ros args r pc) - | hstailcall_ref: forall hros ros hargs args s, - sum_refines hros ros -> - list_refines hargs args -> - hfinal_refines (HStailcall s hros hargs) (Stailcall s ros args) - | hsbuiltin_ref: forall ef lbha lba br pc, - list_forall2 barg_refines lbha lba -> - hfinal_refines (HSbuiltin ef lbha br pc) (Sbuiltin ef lba br pc) - | hsjumptable_ref: forall hsv sv lpc, - sval_refines hsv sv -> hfinal_refines (HSjumptable hsv lpc) (Sjumptable sv lpc) - | hsreturn_ref: forall ohsv osv, - option_refines ohsv osv -> hfinal_refines (HSreturn ohsv) (Sreturn osv). - -Remark hfinal_refines_snone: hfinal_refines HSnone Snone. -Proof. constructor. Qed. - -End HFINAL_REFINES. - -Lemma list_proj_refines_eq ge ge' sp rs0 m0: forall lsv lhsv, - (forall s, Genv.find_symbol ge s = Genv.find_symbol ge' s) -> - list_refines ge sp rs0 m0 lhsv lsv -> - forall lhsv' lsv', - list_refines ge' sp rs0 m0 lhsv' lsv' -> - hsval_list_proj lhsv = hsval_list_proj lhsv' -> - seval_list_sval ge sp lsv rs0 m0 = seval_list_sval ge' sp lsv' rs0 m0. -Proof. - induction 2; rename H into GFS. - - simpl. intros. destruct lhsv'; try discriminate. clear H0. - inv H. simpl. reflexivity. - - simpl. intros. destruct lhsv'; try discriminate. - simpl in H2. inv H2. destruct lsv'; [inv H|]. - inv H. simpl. - assert (SVALEQ: seval_sval ge sp sv rs0 m0 = seval_sval ge' sp sv0 rs0 m0). { - rewrite <- H10. rewrite <- H1. unfold seval_hsval. erewrite <- seval_preserved; [| eapply GFS]. congruence. - } rewrite SVALEQ. - erewrite IHlist_refines; eauto. -Qed. - -Lemma sval_refines_proj ge ge' sp rs m hsv sv hsv' sv': - (forall s, Genv.find_symbol ge s = Genv.find_symbol ge' s) -> - sval_refines ge sp rs m hsv sv -> - sval_refines ge' sp rs m hsv' sv' -> - hsval_proj hsv = hsval_proj hsv' -> - seval_sval ge sp sv rs m = seval_sval ge' sp sv' rs m. -Proof. - intros GFS REF REF' PROJ. - rewrite <- REF. rewrite <- REF'. unfold seval_hsval. - erewrite <- seval_preserved; [| eapply GFS]. - congruence. -Qed. - -Lemma barg_proj_refines_eq_single ge ge' sp rs0 m0: - (forall s, Genv.find_symbol ge s = Genv.find_symbol ge' s) -> - forall hsv sv, barg_refines ge sp rs0 m0 hsv sv -> - forall hsv' sv', barg_refines ge' sp rs0 m0 hsv' sv' -> - barg_proj hsv = barg_proj hsv' -> - seval_builtin_sval ge sp sv rs0 m0 = seval_builtin_sval ge' sp sv' rs0 m0. -Proof. - intro GFS. induction 1. - all: try (simpl; intros hsv' sv' BREF' BPROJ'; - destruct hsv'; simpl in BPROJ'; try discriminate; - inv BPROJ'; inv BREF'; simpl; try reflexivity; - erewrite sval_refines_proj; eauto). -(* BA_splitlong *) - - simpl. intros hsv' sv' BREF' BPROJ'. - destruct hsv'; simpl in BPROJ'; try discriminate. - inv BPROJ'. inv BREF'. simpl. - erewrite IHbarg_refines2; eauto. - erewrite IHbarg_refines1. 2: eapply H5. - all: eauto. -(* BA_addptr *) - - simpl. intros hsv' sv' BREF' BPROJ'. - destruct hsv'; simpl in BPROJ'; try discriminate. - inv BPROJ'. inv BREF'. simpl. - erewrite IHbarg_refines2; eauto. - erewrite IHbarg_refines1. 2: eapply H5. - all: eauto. -Qed. - -Lemma barg_proj_refines_eq ge ge' sp rs0 m0: forall lsv lhsv, - (forall s, Genv.find_symbol ge s = Genv.find_symbol ge' s) -> - list_forall2 (barg_refines ge sp rs0 m0) lhsv lsv -> - forall lhsv' lsv', - list_forall2 (barg_refines ge' sp rs0 m0) lhsv' lsv' -> - barg_list_proj lhsv = barg_list_proj lhsv' -> - seval_list_builtin_sval ge sp lsv rs0 m0 = seval_list_builtin_sval ge' sp lsv' rs0 m0. -Proof. - induction 2; rename H into GFS. - - simpl. intros. destruct lhsv'; try discriminate. clear H0. - inv H. simpl. reflexivity. - - simpl. intros. destruct lhsv'; try discriminate. - simpl in H2. inv H2. destruct lsv'; [inv H|]. - inv H. simpl. - erewrite barg_proj_refines_eq_single; eauto. - erewrite IHlist_forall2; eauto. -Qed. - -Definition final_simu_core (dm: PTree.t node) (f: RTLpath.function) (pc1 pc2: node) (f1 f2: sfval): Prop := - match f1 with - | Scall sig1 svos1 lsv1 res1 pc1 => - match f2 with - | Scall sig2 svos2 lsv2 res2 pc2 => - dm ! pc2 = Some pc1 /\ sig1 = sig2 /\ svos1 = svos2 /\ lsv1 = lsv2 /\ res1 = res2 - | _ => False - end - | Sbuiltin ef1 lbs1 br1 pc1 => - match f2 with - | Sbuiltin ef2 lbs2 br2 pc2 => - dm ! pc2 = Some pc1 /\ ef1 = ef2 /\ lbs1 = lbs2 /\ br1 = br2 - | _ => False - end - | Sjumptable sv1 lpc1 => - match f2 with - | Sjumptable sv2 lpc2 => - ptree_get_list dm lpc2 = Some lpc1 /\ sv1 = sv2 - | _ => False - end - | Snone => - match f2 with - | Snone => dm ! pc2 = Some pc1 - | _ => False - end - (* Stailcall, Sreturn *) - | _ => f1 = f2 - end. - -Definition hfinal_simu_core (dm: PTree.t node) (f: RTLpath.function) (pc1 pc2: node) (hf1 hf2: hsfval): Prop := - final_simu_core dm f pc1 pc2 (hfinal_proj hf1) (hfinal_proj hf2). - -Lemma svident_simu_refl f ctx s: - svident_simu f ctx s s. -Proof. - destruct s; constructor; [| reflexivity]. - erewrite <- seval_preserved; [| eapply ctx]. constructor. -Qed. - -Theorem hfinal_simu_core_correct dm f ctx opc1 opc2 hf1 hf2 f1 f2: - hfinal_simu_core dm f opc1 opc2 hf1 hf2 -> - hfinal_refines (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hf1 f1 -> - hfinal_refines (the_ge2 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hf2 f2 -> - sfval_simu dm f opc1 opc2 ctx f1 f2. -Proof. - assert (GFS: forall s : ident, Genv.find_symbol (the_ge1 ctx) s = Genv.find_symbol (the_ge2 ctx) s) by apply ctx. - intros CORE FREF1 FREF2. - destruct hf1; inv FREF1. - (* Snone *) - - destruct hf2; try contradiction. inv FREF2. - inv CORE. constructor. assumption. - (* Scall *) - - rename H5 into SREF1. rename H6 into LREF1. - destruct hf2; try contradiction. inv FREF2. - rename H5 into SREF2. rename H6 into LREF2. - destruct CORE as (PCEQ & ? & ? & ? & ?). subst. - rename H0 into SVOSEQ. rename H1 into LSVEQ. - constructor; [assumption | |]. - + destruct svos. - * destruct svos0; try discriminate. destruct ros; try contradiction. - destruct ros0; try contradiction. constructor. - simpl in SVOSEQ. inv SVOSEQ. - simpl in SREF1. simpl in SREF2. - rewrite <- SREF1. rewrite <- SREF2. unfold seval_hsval. - erewrite <- seval_preserved; [| eapply GFS]. congruence. - * destruct svos0; try discriminate. destruct ros; try contradiction. - destruct ros0; try contradiction. constructor. - simpl in SVOSEQ. inv SVOSEQ. congruence. - + erewrite list_proj_refines_eq; eauto. constructor. - (* Stailcall *) - - rename H3 into SREF1. rename H4 into LREF1. - destruct hf2; try (inv CORE; fail). inv FREF2. - rename H4 into LREF2. rename H3 into SREF2. - inv CORE. rename H1 into SVOSEQ. rename H2 into LSVEQ. - constructor. - + destruct svos. (** Copy-paste from Scall *) - * destruct svos0; try discriminate. destruct ros; try contradiction. - destruct ros0; try contradiction. constructor. - simpl in SVOSEQ. inv SVOSEQ. - simpl in SREF1. simpl in SREF2. - rewrite <- SREF1. rewrite <- SREF2. unfold seval_hsval. - erewrite <- seval_preserved; [| eapply GFS]. congruence. - * destruct svos0; try discriminate. destruct ros; try contradiction. - destruct ros0; try contradiction. constructor. - simpl in SVOSEQ. inv SVOSEQ. congruence. - + erewrite list_proj_refines_eq; eauto. constructor. - (* Sbuiltin *) - - rename H4 into BREF1. destruct hf2; try (inv CORE; fail). inv FREF2. - rename H4 into BREF2. inv CORE. destruct H0 as (? & ? & ?). subst. - rename H into PCEQ. rename H1 into ARGSEQ. constructor; [assumption|]. - erewrite barg_proj_refines_eq; eauto. constructor. - (* Sjumptable *) - - rename H2 into SREF1. destruct hf2; try contradiction. inv FREF2. - rename H2 into SREF2. destruct CORE as (A & B). constructor; [assumption|]. - erewrite sval_refines_proj; eauto. constructor. - (* Sreturn *) - - rename H0 into SREF1. - destruct hf2; try discriminate. inv CORE. - inv FREF2. destruct osv; destruct res; inv SREF1. - + destruct res0; try discriminate. destruct osv0; inv H1. - constructor. simpl in H0. inv H0. erewrite sval_refines_proj; eauto. - constructor. - + destruct res0; try discriminate. destruct osv0; inv H1. constructor. -Qed. - -Definition hsexec_final (i: instruction) (hst: PTree.t hsval): ?? hsfval := - match i with - | Icall sig ros args res pc => - DO svos <~ hsum_left hst ros;; - DO sargs <~ hlist_args hst args;; - RET (HScall sig svos sargs res pc) - | Itailcall sig ros args => - DO svos <~ hsum_left hst ros;; - DO sargs <~ hlist_args hst args;; - RET (HStailcall sig svos sargs) - | Ibuiltin ef args res pc => - DO sargs <~ hbuiltin_args hst args;; - RET (HSbuiltin ef sargs res pc) - | Ijumptable reg tbl => - DO sv <~ hsi_sreg_get hst reg;; - RET (HSjumptable sv tbl) - | Ireturn or => - match or with - | Some r => DO hr <~ hsi_sreg_get hst r;; RET (HSreturn (Some hr)) - | None => RET (HSreturn None) - end - | _ => RET (HSnone) - end. - -Lemma sval_refines_local_get ge sp rs0 m0 hsl sl r: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - WHEN hsi_sreg_get hsl r ~> hsv THEN - sval_refines ge sp rs0 m0 hsv (si_sreg sl r). -Proof. - intros HOK HREF. wlp_intro hsv. unfold sval_refines. - erewrite <- hsi_sreg_eval_correct; eauto. - destruct HREF as (_ & _ & A & _). rewrite <- A; [| assumption]. - reflexivity. -Qed. - -Lemma hsum_left_correct ge sp rs0 m0 hsl sl ros: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - WHEN hsum_left hsl ros ~> svos THEN - sum_refines ge sp rs0 m0 svos (sum_left_map (si_sreg sl) ros). -Proof. - intros HOK HREF. destruct ros; [| wlp_simplify]. - wlp_bind hr. wlp_simplify. unfold sval_refines. - rewrite sval_refines_local_get; eauto. -Qed. - -Lemma hSnil_correct: - WHEN hSnil () ~> shv THEN hsval_list_proj shv = Snil. -Proof. - wlp_simplify. unfold hSnil in Hexta. apply hC_list_hsval_correct in Hexta. - simpl in *. symmetry. assumption. -Qed. -Global Opaque hSnil. -Hint Resolve hSnil_correct: wlp. - -Lemma hScons_correct: forall lhsv hsv, - WHEN hScons hsv lhsv ~> lhsv' THEN - hsval_list_proj lhsv' = Scons (hsval_proj hsv) (hsval_list_proj lhsv). -Proof. - destruct lhsv; wlp_simplify. - - unfold hScons in Hexta. apply hC_list_hsval_correct in Hexta. - simpl in *. congruence. - - unfold hScons in Hexta. apply hC_list_hsval_correct in Hexta. simpl in *. congruence. -Qed. -Global Opaque hScons. -Hint Resolve hScons_correct: wlp. - -Lemma hsi_sreg_get_refines ge sp rs0 m0 hsl sl r: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - WHEN hsi_sreg_get hsl r ~> hsv THEN - sval_refines ge sp rs0 m0 hsv (si_sreg sl r). -Proof. - intros HOK HREF. wlp_intro hsv. destruct HREF as (_ & _ & A & _). - unfold sval_refines. erewrite <- hsi_sreg_eval_correct by eassumption. - rewrite A by assumption. reflexivity. -Qed. - -Lemma hsval_list_proj_correct ge sp rs m lsv: forall lhsv, - list_refines ge sp rs m lhsv lsv -> - forall lhsv', hsval_list_proj lhsv' = hsval_list_proj lhsv -> - list_refines ge sp rs m lhsv' lsv. -Proof. - induction 1. - - intro. simpl. intros. destruct lhsv'; try discriminate. constructor. - - intros. simpl in H1. destruct lhsv'; try discriminate. - simpl in H1. inv H1. apply IHlist_refines in H4. - constructor; [assumption|]. - unfold sval_refines. unfold seval_hsval. rewrite H3. assumption. -Qed. -Hint Resolve hsval_list_proj_correct: wlp. - -Lemma hsval_proj_correct ge sp rs0 m0 hsl sl hsv r: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - WHEN hsi_sreg_get hsl r ~> hsv' THEN - hsval_proj hsv = hsval_proj hsv' -> - sval_refines ge sp rs0 m0 hsv (si_sreg sl r). -Proof. - intros HOK HREF. wlp_intro hsv'. intros PROJ. - unfold sval_refines. unfold seval_hsval. - rewrite PROJ. enough (seval_sval ge sp (hsval_proj hsv') rs0 m0 = seval_hsval ge sp hsv' rs0 m0) as ->; [|reflexivity]. - erewrite hsi_sreg_get_refines; eauto. -Qed. -Hint Resolve hsval_proj_correct: wlp. - -Lemma hlist_args_correct ge sp rs0 m0 hsl sl: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - forall lr, WHEN hlist_args hsl lr ~> shv THEN - list_refines ge sp rs0 m0 shv (list_sval_inj (List.map (si_sreg sl) lr)). -Proof. - intros HOK HREF. induction lr. - - simpl. wlp_simplify. destruct exta; try discriminate. constructor. - - simpl. wlp_bind v. wlp_bind lhsv. wlp_simplify. - apply IHlr in Hlhsv. clear IHlr. - destruct exta; try discriminate. simpl in H. inv H. constructor. - + eapply hsval_list_proj_correct; eauto. - + eapply hsval_proj_correct; eauto. -Qed. -Global Opaque hlist_args. -Hint Resolve hlist_args_correct: wlp. - -Lemma hbuiltin_arg_correct ge sp rs0 m0 hsl sl: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - forall br, - WHEN hbuiltin_arg hsl br ~> bhsv THEN - barg_refines ge sp rs0 m0 bhsv (builtin_arg_map (si_sreg sl) br). -Proof. - intros HOK HREF. - induction br. - all: try (wlp_simplify; constructor; auto; fail). - (* BA *) - - simpl. wlp_bind hsv. wlp_simplify. constructor. eapply hsi_sreg_get_refines; eauto. -Qed. - -Lemma hbuiltin_args_correct ge sp rs0 m0 hsl sl: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - forall lbr, - WHEN hbuiltin_args hsl lbr ~> lbhsv THEN - list_forall2 (barg_refines ge sp rs0 m0) lbhsv (List.map (builtin_arg_map (si_sreg sl)) lbr). -Proof. - intros HOK HREF. - induction lbr; [wlp_simplify; constructor|]. - simpl. wlp_bind ha. wlp_bind hl. wlp_simplify. - constructor; [|auto]. eapply hbuiltin_arg_correct; eauto. -Qed. - -Lemma hsexec_final_correct ge sp rs0 m0 hsl sl i: - hsok_local ge sp rs0 m0 hsl -> - hsilocal_refines ge sp rs0 m0 hsl sl -> - WHEN hsexec_final i hsl ~> hsf THEN - hfinal_refines ge sp rs0 m0 hsf (sexec_final i sl). -Proof. - intro HOK. - destruct i; simpl; intros HLREF; try (wlp_simplify; apply hfinal_refines_snone). - (* Scall *) - - wlp_bind svos. wlp_bind sargs. wlp_simplify. constructor. - + eapply hsum_left_correct; eauto. - + eapply hlist_args_correct; eauto. - (* Stailcall *) - - wlp_bind svos. wlp_bind sargs. wlp_simplify. constructor. - + eapply hsum_left_correct; eauto. - + eapply hlist_args_correct; eauto. - (* Sbuiltin *) - - wlp_simplify. constructor. eapply hbuiltin_args_correct; eauto. - (* Sjumptable *) - - wlp_bind sv. wlp_simplify. constructor. eapply hsi_sreg_get_refines; eauto. - (* Sreturn *) - - destruct o. - -- wlp_bind sv. wlp_simplify. constructor. simpl. - eapply hsi_sreg_get_refines; eauto. - -- wlp_simplify. repeat constructor. -Qed. + hsiexits_simu_check dm f (hsi_exits hst1) (hsi_exits hst2);; + hsilocal_simu_check (hsi_local hst1) (hsi_local hst2). Fixpoint revmap_check_list (dm: PTree.t node) (ln ln': list node): ?? unit := match ln, ln' with @@ -1701,17 +947,6 @@ Fixpoint revmap_check_list (dm: PTree.t node) (ln ln': list node): ?? unit := | _, _ => FAILWITH "revmap_check_list: lists have different lengths" end. -Lemma revmap_check_list_correct dm: forall lpc lpc', - WHEN revmap_check_list dm lpc lpc' ~> tt THEN - ptree_get_list dm lpc' = Some lpc. -Proof. - induction lpc. - - destruct lpc'; wlp_simplify. - - destruct lpc'; wlp_simplify. rewrite H. rewrite H0. reflexivity. -Qed. -Global Opaque revmap_check_list. -Hint Resolve revmap_check_list_correct: wlp. - Definition svos_simu_check (svos1 svos2: hsval + ident) := match svos1, svos2 with | inl sv1, inl sv2 => phys_check sv1 sv2 "svos_simu_check: sval mismatch" @@ -1719,62 +954,18 @@ Definition svos_simu_check (svos1 svos2: hsval + ident) := | _, _ => FAILWITH "svos_simu_check: type mismatch" end. -Lemma svos_simu_check_correct svos1 svos2: - WHEN svos_simu_check svos1 svos2 ~> tt THEN - svos1 = svos2. -Proof. - destruct svos1; destruct svos2; wlp_simplify; try wlp_absurd. - all: congruence. -Qed. -Global Opaque svos_simu_check. -Hint Resolve svos_simu_check_correct: wlp. - Fixpoint builtin_arg_simu_check (bs bs': builtin_arg hsval) := - match bs with - | BA sv => - match bs' with - | BA sv' => phys_check sv sv' "builtin_arg_simu_check: sval mismatch" - | _ => FAILWITH "builtin_arg_simu_check: BA mismatch" - end - | BA_splitlong lo hi => - match bs' with - | BA_splitlong lo' hi' => - builtin_arg_simu_check lo lo';; - builtin_arg_simu_check hi hi' - | _ => FAILWITH "builtin_arg_simu_check: BA_splitlong mismatch" - end - | BA_addptr b1 b2 => - match bs' with - | BA_addptr b1' b2' => - builtin_arg_simu_check b1 b1';; - builtin_arg_simu_check b2 b2' - | _ => FAILWITH "builtin_arg_simu_check: BA_addptr mismatch" - end - | bs => struct_check bs bs' "builtin_arg_simu_check: basic mismatch" + match bs, bs' with + | BA sv, BA sv' => phys_check sv sv' "builtin_arg_simu_check: sval mismatch" + | BA_splitlong lo hi, BA_splitlong lo' hi' => + builtin_arg_simu_check lo lo';; + builtin_arg_simu_check hi hi' + | BA_addptr b1 b2, BA_addptr b1' b2' => + builtin_arg_simu_check b1 b1';; + builtin_arg_simu_check b2 b2' + | _, _ => struct_check bs bs' "builtin_arg_simu_check: basic mismatch" end. -Lemma builtin_arg_simu_check_correct: forall bs1 bs2, - WHEN builtin_arg_simu_check bs1 bs2 ~> tt THEN - barg_proj bs1 = barg_proj bs2. -Proof. - induction bs1. - all: try (intros; simpl; wlp_simplify; subst; reflexivity). - (* BA *) - - destruct bs2; wlp_simplify; try wlp_absurd. congruence. - (* BA_splitlong *) - - destruct bs2; try (wlp_simplify; wlp_absurd). simpl. - wlp_bind b1. wlp_intro b2. - rewrite IHbs1_1 by eassumption. rewrite IHbs1_2 by eassumption. - reflexivity. - (* BA_addptr *) - - destruct bs2; try (wlp_simplify; wlp_absurd). simpl. - wlp_bind b1. wlp_intro b2. - rewrite IHbs1_1 by eassumption. rewrite IHbs1_2 by eassumption. - reflexivity. -Qed. -Global Opaque builtin_arg_simu_check. -Hint Resolve builtin_arg_simu_check_correct: wlp. - Fixpoint list_builtin_arg_simu_check lbs1 lbs2 := match lbs1, lbs2 with | nil, nil => RET tt @@ -1784,22 +975,9 @@ Fixpoint list_builtin_arg_simu_check lbs1 lbs2 := | _, _ => FAILWITH "list_builtin_arg_simu_check: length mismatch" end. -Lemma list_builtin_arg_simu_check_correct: forall lbs1 lbs2, - WHEN list_builtin_arg_simu_check lbs1 lbs2 ~> tt THEN - barg_list_proj lbs1 = barg_list_proj lbs2. -Proof. - induction lbs1. - - wlp_simplify. destruct lbs2; [simpl; reflexivity|]. - simpl in Hexta. wlp_absurd. - - destruct lbs2; wlp_simplify; try wlp_absurd. - congruence. -Qed. -Global Opaque list_builtin_arg_simu_check. -Hint Resolve list_builtin_arg_simu_check_correct: wlp. - -Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (opc1 opc2: node) (fv1 fv2: hsfval) := +Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (pc1 pc2: node) (fv1 fv2: hsfval) := match fv1, fv2 with - | HSnone, HSnone => revmap_check_single dm opc1 opc2 + | HSnone, HSnone => revmap_check_single dm pc1 pc2 | HScall sig1 svos1 lsv1 res1 pc1, HScall sig2 svos2 lsv2 res2 pc2 => revmap_check_single dm pc1 pc2;; phys_check sig1 sig2 "sfval_simu_check: Scall different signatures";; @@ -1823,534 +1001,10 @@ Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (opc1 opc2: | _, _ => FAILWITH "sfval_simu_check: structure mismatch" end. - -Theorem sfval_simu_check_correct dm f opc1 opc2 fv1 fv2: - WHEN sfval_simu_check dm f opc1 opc2 fv1 fv2 ~> tt THEN - hfinal_simu_core dm f opc1 opc2 fv1 fv2. -Proof. - destruct fv1; destruct fv2; try (wlp_simplify; simpl in Hexta; wlp_absurd). - (* HScall *) - - simpl. wlp_bind u1 REVMAP. wlp_bind u2 SIG. wlp_bind u3 RES. - wlp_bind u4 SVOS. wlp_intro u5 LSV. - apply phys_check_correct in SIG. apply phys_check_correct in RES. - apply revmap_check_single_correct in REVMAP. apply phys_check_correct in LSV. - apply svos_simu_check_correct in SVOS. subst. repeat (constructor; auto). - (* HStailcall *) - - simpl. wlp_bind u1 SIG. wlp_bind u2 SVOS. wlp_intro u3 LSV. - apply phys_check_correct in SIG. apply phys_check_correct in LSV. - apply svos_simu_check_correct in SVOS. subst. repeat (constructor; auto). - (* HSbuiltin *) - - simpl. wlp_bind u1 RMAP. wlp_bind u2 EF. wlp_bind u3 RES. - wlp_intro u4 SARGS. - apply phys_check_correct in EF. apply phys_check_correct in RES. - apply list_builtin_arg_simu_check_correct in SARGS. apply revmap_check_single_correct in RMAP. - subst. repeat (constructor; auto). - (* HSjumptable *) - - simpl. wlp_simplify. subst. constructor; auto. - (* HSreturn *) - - wlp_simplify. subst. reflexivity. -Qed. -Hint Resolve sfval_simu_check_correct: wlp. -Global Opaque hfinal_simu_core. - -Definition hsstate_refines (hst: hsstate) (st:sstate): Prop := - hsistate_refines_stat (hinternal hst) (internal st) - /\ (forall ge sp rs0 m0, hsistate_refines_dyn ge sp rs0 m0 (hinternal hst) (internal st) - /\ hfinal_refines ge sp rs0 m0 (hfinal hst) (final st)) -. - -Definition hsstate_simu_core (dm: PTree.t node) (f: RTLpath.function) (hst1 hst2: hsstate) := - hsistate_simu_core dm f (hinternal hst1) (hinternal hst2) - /\ hfinal_simu_core dm f (hsi_pc (hinternal hst1)) (hsi_pc (hinternal hst2)) (hfinal hst1) (hfinal hst2). - -Definition hsstate_simu dm f (hst1 hst2: hsstate) ctx: Prop := - forall st1 st2, - hsstate_refines hst1 st1 -> - hsstate_refines hst2 st2 -> sstate_simu dm f st1 st2 ctx. - -Theorem hsstate_simu_core_correct dm f ctx hst1 hst2: - hsstate_simu_core dm f hst1 hst2 -> - hsstate_simu dm f hst1 hst2 ctx. -Proof. - intros (SCORE & FSIMU). intros st1 st2 HREF1 HREF2. - destruct HREF1 as (SREF1 & DREF1 & FREF1). destruct HREF2 as (SREF2 & DREF2 & FREF2). - assert (PCEQ: dm ! (hsi_pc hst2) = Some (hsi_pc hst1)) by apply SCORE. - eapply hsistate_simu_core_correct in SCORE. - eapply hfinal_simu_core_correct in FSIMU; eauto. - constructor; [apply SCORE; auto|]. 1-2: eassumption. - destruct SREF1 as (PC1 & _). destruct SREF2 as (PC2 & _). rewrite <- PC1. rewrite <- PC2. - eapply FSIMU. -Qed. - Definition hsstate_simu_check (dm: PTree.t node) (f: RTLpath.function) (hst1 hst2: hsstate) := hsistate_simu_check dm f (hinternal hst1) (hinternal hst2);; sfval_simu_check dm f (hsi_pc hst1) (hsi_pc hst2) (hfinal hst1) (hfinal hst2). -Theorem hsstate_simu_check_correct dm f hst1 hst2: - WHEN hsstate_simu_check dm f hst1 hst2 ~> tt THEN - hsstate_simu_core dm f hst1 hst2. -Proof. - wlp_simplify. constructor. 1-2: assumption. -Qed. -Hint Resolve hsstate_simu_check_correct: wlp. -Global Opaque hsstate_simu_core. - -Definition seval_list_hsval ge sp lhsv rs m := seval_list_sval ge sp (hsval_list_proj lhsv) rs m. - -Definition hok_args ge sp rs0 m0 hst lr := - WHEN hlist_args (hsi_sreg hst) lr ~> lhsv THEN - hsok_local ge sp rs0 m0 hst -> - (seval_list_hsval ge sp lhsv rs0 m0 <> None). - -Lemma hsist_set_local_correct_dyn ge sp rs0 m0 hst st pc hnxt nxt: - hsistate_refines_dyn ge sp rs0 m0 hst st -> - hsilocal_refines ge sp rs0 m0 hnxt nxt -> - (sok_local ge sp rs0 m0 nxt -> sok_local ge sp rs0 m0 (si_local st)) -> - hsistate_refines_dyn ge sp rs0 m0 (hsist_set_local hst pc hnxt) (sist_set_local st pc nxt). -Proof. - unfold hsistate_refines_dyn; simpl. - intros (EREF & LREF & NESTED) LREFN SOK; intuition. - destruct NESTED as [|st0 se lse TOP NEST]; econstructor; simpl; auto. -Qed. - -(* Completely lost on that one *) -(* Lemma hsok_local_set_sreg ge sp rs0 m0 hst r (rsv:root_sval) lr: - WHEN hslocal_set_sreg hst r rsv lr ~> hst' THEN - hok_args ge sp rs0 m0 hst lr -> - hsok_local ge sp rs0 m0 hst' - <-> (hsok_local ge sp rs0 m0 hst /\ (WHEN root_apply rsv lr hst ~> hsv THEN seval_hsval ge sp hsv rs0 m0 <> None)). -Proof. - unfold hslocal_set_sreg. wlp_bind lhsvok. wlp_bind hsv. wlp_ret hst'. - intros HOK. - destruct may_trap eqn: MAYTRAP. - - wlp_hbind hv. wlp_hret. constructor. - + unfold hsok_local. simpl. intro. constructor. - * intros. apply H. right. assumption. - * wlp_intro hsv'. apply H. - - - unfold hok_args, hsok_local. simpl. - - unfold hslocal_set_sreg, ok_args, hsok_local; simpl. - destruct may_trap eqn: MAYTRAP; simpl; intuition (subst; eauto). - eapply may_trap_correct; eauto. -Qed. *) - -Lemma seval_list_sval_proj ge sp rs0 m0: forall lhsv lsv, - list_refines ge sp rs0 m0 lhsv lsv -> - seval_list_sval ge sp (hsval_list_proj lhsv) rs0 m0 = seval_list_sval ge sp lsv rs0 m0. -Proof. - induction lhsv. - - destruct lsv; simpl; intros H; [reflexivity | inv H]. - - destruct lsv; [intro H; inv H|]. - intros. inv H. simpl. erewrite IHlhsv; eauto. - rewrite H6. reflexivity. -Qed. - -Lemma hSop_correct ge sp rs0 m0 op lhsv lsv hst st: - WHEN hSop op lhsv (hsi_smem hst) ~> hsv THEN - hsok_local ge sp rs0 m0 hst -> - list_refines ge sp rs0 m0 lhsv lsv -> - hsilocal_refines ge sp rs0 m0 hst st -> - seval_hsval ge sp hsv rs0 m0 = seval_sval ge sp (Sop op lsv (si_smem st)) rs0 m0. -Proof. - wlp_simplify. apply hC_hsval_correct in Hexta1. simpl in *. unfold seval_hsval. - rewrite <- Hexta1. simpl. clear Hexta1. - erewrite seval_list_sval_proj; eauto. clear H0. - destruct H1 as (A & B & C & D). rewrite <- B; eauto. -Qed. - -(** Version of hSop_correct with weaker hypothesis *) -Lemma hSop_correct_mem ge sp rs0 m0 op lhsv lsv hsm sm: - WHEN hSop op lhsv hsm ~> hsv THEN - seval_hsmem ge sp hsm rs0 m0 = seval_smem ge sp sm rs0 m0 -> - list_refines ge sp rs0 m0 lhsv lsv -> - seval_hsval ge sp hsv rs0 m0 = seval_sval ge sp (Sop op lsv sm) rs0 m0. -Proof. - wlp_simplify. apply hC_hsval_correct in Hexta1. simpl in *. unfold seval_hsval. - rewrite <- Hexta1. simpl. clear Hexta1. - erewrite seval_list_sval_proj; eauto. clear H0. - rewrite <- H. eauto. -Qed. - -Lemma hSload_correct ge sp rs0 m0 lhsv lsv hst st trap addr chunk: - WHEN hSload (hsi_smem hst) trap chunk addr lhsv ~> hsv THEN - hsok_local ge sp rs0 m0 hst -> - list_refines ge sp rs0 m0 lhsv lsv -> - hsilocal_refines ge sp rs0 m0 hst st -> - seval_hsval ge sp hsv rs0 m0 = seval_sval ge sp (Sload (si_smem st) trap chunk addr lsv) rs0 m0. -Proof. - wlp_simplify. apply hC_hsval_correct in Hexta3. simpl in *. unfold seval_hsval. - rewrite <- Hexta3. simpl. clear Hexta3. - erewrite seval_list_sval_proj; eauto. clear H0. - destruct H1 as (A & B & C & D). rewrite <- B; eauto. -Qed. - -Lemma hsinit_sinit ge sp rs0 m0: - WHEN hSinit () ~> init THEN - seval_hsmem ge sp init rs0 m0 = seval_smem ge sp Sinit rs0 m0. -Proof. - wlp_intro init. eapply hsinit_seval_hsmem in Hinit; eauto. -Qed. - -Lemma simplify_correct (rsv: root_sval) lr (ge: RTL.genv) (sp: val) rs0 m0 v hst st: - WHEN root_apply rsv lr hst ~> hsv THEN - hsok_local ge sp rs0 m0 hst -> - hsilocal_refines ge sp rs0 m0 hst st -> - seval_hsval ge sp hsv rs0 m0 = Some v -> - WHEN simplify rsv lr hst ~> hsv' THEN - seval_hsval ge sp hsv' rs0 m0 = Some v. -Proof. - wlp_bind lhsv. wlp_intro hsv. intros HOK HREF HEVAL. - eapply hlist_args_correct in Hlhsv; eauto. - destruct rsv; simpl. - (* Rop *) - - exploit hSop_correct; eauto. intros EVALMOV. clear Hlhsv. clear Hhsv. - destruct (is_move_operation _ _) eqn:IMOVE. - + apply is_move_operation_correct in IMOVE. inv IMOVE. - rewrite <- HEVAL. rewrite EVALMOV. wlp_intro hsv'. - simpl. destruct HREF as (A & B & C & D). rewrite <- C; eauto. - rewrite hsi_sreg_eval_correct; eauto. - destruct (seval_hsval ge sp hsv' rs0 m0); [|reflexivity]. - apply A in HOK. destruct HOK as (_ & MOK & _). - destruct (seval_smem _ _ _ _ _); [reflexivity|contradiction]. - + clear IMOVE. wlp_bind hsm. wlp_bind lhsv'. wlp_intro hsv'. - eapply hlist_args_correct in Hlhsv'; eauto. - rewrite hSop_correct_mem; eauto; [|eapply hsinit_sinit; eauto]. - clear Hlhsv'. clear Hhsv'. rewrite <- HEVAL. rewrite EVALMOV. - admit. (** Voir avec Sylvain - je ne sais plus où on en est sur les dépendances mémoires avec les op *) - (* Rload *) - - exploit hSload_correct; eauto. intros EVALLOAD. - wlp_bind lhsv'. wlp_intro hsv'. eapply hlist_args_correct in Hlhsv'; eauto. - rewrite hSload_correct; eauto. rewrite EVALLOAD in HEVAL. - destruct trap; simpl; auto. simpl in HEVAL. - destruct (seval_list_sval _ _ _ _) as [args|] eqn: Hargs; try congruence. - destruct (eval_addressing _ _ _ _) as [a|] eqn: Ha; try congruence. - destruct (seval_smem _ _ _ _) as [m|] eqn: Hm; try congruence. - rewrite HEVAL. reflexivity. -Admitted. - -Lemma hSop_preserves_hok ge sp op lhsv rs m hst: - seval_list_hsval ge sp lhsv rs m <> None -> - hsok_local ge sp rs m hst -> - WHEN hSop op lhsv hst ~> hsv THEN - seval_hsval ge sp hsv rs m <> None. -Proof. -Abort. -(* FIXME - that theorem is false! *) - -Lemma root_apply_preserves_hok ge sp rs m hst lr rsv: - hok_args ge sp rs m hst lr -> - hsok_local ge sp rs m hst -> - WHEN root_apply rsv lr hst ~> hsv THEN - seval_hsval ge sp hsv rs m <> None. -Proof. - intros ARGSOK HOKL. unfold root_apply. wlp_bind lhsv. wlp_intro hsv. - destruct rsv. - - (* eapply hSop_preserves_hok; eauto. *) -Abort. -(* FIXME - the theorem is wrong *) - -Lemma hsok_local_set_sreg ge sp rs0 m0 hst r (rsv:root_sval) lr: - hok_args ge sp rs0 m0 hst lr -> - WHEN hslocal_set_sreg hst r rsv lr ~> hst' THEN - hsok_local ge sp rs0 m0 hst' - <-> (hsok_local ge sp rs0 m0 hst /\ - (WHEN root_apply rsv lr hst ~> hsv' THEN seval_hsval ge sp hsv' rs0 m0 <> None)). -Proof. - intros HOK. unfold hslocal_set_sreg. - wlp_bind ok_lhsv. wlp_bind hsv'. wlp_intro hst'. wlp_hret. - constructor. - - intros HOKL. - assert (HOKL': hsok_local ge sp rs0 m0 hst). { - destruct may_trap. - * wlp_hbind hv. wlp_hret. unfold hsok_local. - intros. apply HOKL. simpl. right. assumption. - * wlp_hret. unfold hsok_local. - intros. apply HOKL. simpl. assumption. } - split; [assumption|]. - wlp_intro hsv2. admit. (* eapply root_apply_preserves_hok; eauto. FIXME - wrong *) - - intros (HOKL & RAPP). destruct (may_trap _ _) eqn:MAYT. - + wlp_hbind hv. wlp_hret. unfold hsok_local. simpl. intros. inv H. - * admit. (* eapply root_apply_preserves_hok; eauto. FIXME - wrong *) - * apply HOKL. assumption. - + wlp_hret. apply HOKL. -Admitted. - -Lemma slocal_set_sreg_preserves_sok ge sp rs m st r sv: - sok_local ge sp rs m st <-> sok_local ge sp rs m (slocal_set_sreg st r sv). -Proof. -Admitted. - -Lemma root_apply_none ge sp rsv rs m hst lr: - hsok_local ge sp rs m hst -> - WHEN root_apply rsv lr hst ~> hsv THEN - seval_hsval ge sp hsv rs m <> None. -Proof. -Admitted. - -Lemma hslocal_set_sreg_preserves_smem ge sp hst rs0 m0 r rsv lr: - WHEN hslocal_set_sreg hst r rsv lr ~> hst' THEN - seval_hsmem ge sp hst' rs0 m0 = seval_hsmem ge sp hst rs0 m0. -Proof. -Admitted. - -Lemma hslocal_set_sreg_preserves_hsok ge sp rs m hst r rsv lr: - WHEN hslocal_set_sreg hst r rsv lr ~> hst' THEN - hsok_local ge sp rs m hst <-> hsok_local ge sp rs m hst'. -Proof. -Admitted. - -Lemma red_PTree_set_correct (r r0:reg) (hsv: hsval) (hst: PTree.t hsval) ge sp rs0 m0: - hsi_sreg_eval ge sp (red_PTree_set r hsv hst) r0 rs0 m0 = hsi_sreg_eval ge sp (PTree.set r hsv hst) r0 rs0 m0. -Proof. - destruct hsv; simpl; auto. - destruct (Pos.eq_dec r r1); auto. - subst; unfold hsi_sreg_eval. - destruct (Pos.eq_dec r0 r1); auto. - - subst; rewrite PTree.grs, PTree.gss; simpl; auto. - - rewrite PTree.gro, PTree.gso; simpl; auto. -Qed. - -(** TODO - express some lemma about root_apply_correct and simplify_correct - * Figure out how to prove this stuff *) -Lemma hslocal_set_sreg_correct ge sp rs0 m0 hst st r (rsv:root_sval) lr sv': - hsilocal_refines ge sp rs0 m0 hst st -> - hok_args ge sp rs0 m0 hst lr -> - ( hsok_local ge sp rs0 m0 hst -> - WHEN root_apply rsv lr hst ~> hsv THEN - seval_sval ge sp sv' rs0 m0 = seval_hsval ge sp hsv rs0 m0) -> - WHEN hslocal_set_sreg hst r rsv lr ~> hst' THEN - hsilocal_refines ge sp rs0 m0 hst' (slocal_set_sreg st r sv'). -Proof. - intros HREF HOK REVAL. wlp_intro hst'. - unfold hsilocal_refines. split; [|split; [|split]]. - + symmetry. eapply iff_trans. eapply hsok_local_set_sreg; eauto. - constructor. - * intros (HOKL & REVAL'). apply slocal_set_sreg_preserves_sok. - destruct HREF as (A & _). apply A in HOKL. assumption. - * intros SOKL. rewrite <- slocal_set_sreg_preserves_sok in SOKL. - destruct HREF as (A & _). apply A in SOKL. - split; [assumption|]. - eapply root_apply_none; eauto. - + intros HOKL. simpl. rewrite hslocal_set_sreg_preserves_smem; eauto. - destruct HREF as (_ & A & _). rewrite A; auto. - eapply hslocal_set_sreg_preserves_hsok; eauto. - + intros HOKL. simpl. intro r0. unfold hslocal_set_sreg in Hhst'. - wlp_hbind ok_lhsv. wlp_hbind hsv'. wlp_hret. simpl. - rewrite red_PTree_set_correct. unfold hsi_sreg_eval. - destruct (Pos.eq_dec r r0). - * subst. rewrite PTree.gss. (* Something about simplify_correct ? *) admit. - * admit. - + admit. - -(* intros (ROK & RMEM & RVAL) OKA RSV. - unfold hsilocal_refines; simpl. rewrite! hsok_local_set_sreg; eauto. split. - + rewrite <- ROK in RSV; rewrite sok_local_set_sreg; eauto. - intuition congruence. - + split; try tauto. - intros (HOKL & RSV2) r0. - rewrite red_PTree_set_correct. - rewrite hsi_sreg_eval_correct. unfold hsi_sreg_get. - destruct (Pos.eq_dec r r0). - * subst. rewrite PTree.gss, RSV; auto. - destruct (seval_sval ge sp (rsv lsv (hsi_smem hst))) eqn: RSV3; simpl; try congruence. - eapply simplify_correct; eauto. - * intros; rewrite PTree.gso; auto. - rewrite <- RVAL, hsi_sreg_eval_correct; auto. *) -Admitted. - - - - -Lemma seval_list_hsval_refines ge sp rs0 m0 hst st lr: - hsok_local ge sp rs0 m0 hst -> - hsilocal_refines ge sp rs0 m0 hst st -> - WHEN hlist_args hst lr ~> lhsv THEN - seval_list_hsval ge sp lhsv rs0 m0 = seval_list_sval ge sp (list_sval_inj (List.map (si_sreg st) lr)) rs0 m0. -Proof. - intros OKL HLREF. wlp_simplify. - destruct lr. - - simpl in *. inv H. reflexivity. - - inv H. simpl. unfold seval_list_hsval. simpl. rewrite H4. erewrite seval_list_sval_proj; eauto. -Qed. - -Lemma seval_list_sval_none ge sp (srs: reg -> sval) rs0 m0: forall lr, - (forall r, seval_sval ge sp (srs r) rs0 m0 <> None) -> - seval_list_sval ge sp (list_sval_inj (List.map srs lr)) rs0 m0 <> None. -Proof. - induction lr. - - simpl. discriminate. - - intro SR. simpl. destruct (seval_sval _ _ _ _ _) eqn:V. - 2: { apply SR in V. inv V. } - destruct (seval_list_sval _ _ _ _ _) eqn:LV. - 2: { apply IHlr in SR. assumption. } - discriminate. -Qed. - -Lemma refines_okargs ge sp rs0 m0 hst st lr: - hsistate_refines_dyn ge sp rs0 m0 hst st -> - hok_args ge sp rs0 m0 (hsi_local hst) lr. -Proof. - unfold hok_args. - intros (_ & HLREF & _). wlp_intro lhsv LHSV. intros OK. - exploit hlist_args_correct; eauto. intro LREF. - erewrite seval_list_hsval_refines; eauto. - destruct HLREF as (OKEQ & _ & _). - rewrite <- OKEQ in OK. - destruct OK as (_ & _ & OK). - apply seval_list_sval_none. assumption. -Qed. - -(* Local Hint Resolve refines_okargs: core. *) -Lemma hsiexec_inst_correct_dyn ge sp rs0 m0 i hst st hst' st': - WHEN hsiexec_inst i hst ~> ohst' THEN - ohst' = Some hst' -> - siexec_inst i st = Some st' -> - hsistate_refines_dyn ge sp rs0 m0 hst st -> hsistate_refines_dyn ge sp rs0 m0 hst' st'. -Proof. - destruct i. - (* Inop *) - - wlp_simplify. inv H. inv H0. auto. - (* Iop *) - - simpl. wlp_bind next NEXT. wlp_simplify. inv H. inv H0. - eapply hsist_set_local_correct_dyn; eauto. - + destruct H1 as (A & B & C). - eapply hslocal_set_sreg_correct; eauto. - { eapply refines_okargs. repeat (econstructor; eauto). } - simpl. intro HOK. unfold root_apply. wlp_bind lhsv LHSV. wlp_intro hsv HSV. - eapply hlist_args_correct in LHSV; eauto. - erewrite hSop_correct; eauto. simpl. reflexivity. - + unfold sok_local; simpl; intros (PRE & MEM & REG). - intuition. - generalize (REG r0); clear REG. - destruct (Pos.eq_dec r r0); simpl; intuition (subst; eauto). - (* Iload *) - - simpl. wlp_bind next NEXT. wlp_simplify. inv H. inv H0. - eapply hsist_set_local_correct_dyn; eauto. - + destruct H1 as (A & B & C). - eapply hslocal_set_sreg_correct; eauto. - { eapply refines_okargs. repeat (econstructor; eauto). } - simpl. intro HOK. unfold root_apply. wlp_bind lhsv LHSV. wlp_intro hsv HSV. - eapply hlist_args_correct in LHSV; eauto. - erewrite hSload_correct; eauto. simpl. reflexivity. - + unfold sok_local; simpl; intros (PRE & MEM & REG). - intuition. - generalize (REG r0); clear REG. - destruct (Pos.eq_dec r r0); simpl; intuition (subst; eauto). - (* Istore *) - - simpl. wlp_bind next NEXT. wlp_simplify. inv H. inv H0. - eapply hsist_set_local_correct_dyn; eauto. - + admit. (** TODO - port hslocal_set_smem_correct *) - + unfold sok_local; simpl; intuition. - (* Icall *) - - admit. - (* Itailcall *) - - admit. - (* Ibuiltin *) - - admit. - (* Icond *) - - admit. - (* Ijumptable *) - - admit. - (* Ireturn *) - - admit. -Admitted. - - -(* PROOF from RTLpathSE_impl.v - destruct i; simpl; intros STEP1 STEP2; inversion_clear STEP1; - inversion_clear STEP2; discriminate || (intro REF; eauto). - - (* Iop *) - eapply hsist_set_local_correct_dyn; eauto. - + eapply hslocal_set_sreg_correct; eauto. - simpl; intros. - erewrite seval_list_sval_refines; eauto. - erewrite seval_smem_refines; eauto. - + unfold sok_local; simpl; intros (PRE & MEM & REG). - intuition. - generalize (REG r0); clear REG. - destruct (Pos.eq_dec r r0); simpl; intuition (subst; eauto). - - (* Iload *) - eapply hsist_set_local_correct_dyn; eauto. - + eapply hslocal_set_sreg_correct; eauto. - simpl; intros. - erewrite seval_list_sval_refines; eauto. - erewrite seval_smem_refines; eauto. - + unfold sok_local; simpl; intros (PRE & MEM & REG). - intuition. - generalize (REG r0); clear REG. - destruct (Pos.eq_dec r r0); simpl; intuition (subst; eauto). - - (* Istore *) - eapply hsist_set_local_correct_dyn; eauto. - + eapply hslocal_set_mem_correct; eauto. - * simpl. simplify_SOME x. - * intros. simpl. - erewrite seval_list_sval_refines; eauto. - erewrite seval_smem_refines; eauto. - erewrite seval_sval_refines; eauto. - + unfold sok_local; simpl; intuition. - - (* Icond *) - destruct REF as (EXREF & LREF & NEST). - split. - + constructor; simpl; auto. - constructor; simpl; auto. - intros; erewrite seval_condition_refines; eauto. - unfold seval_condition. - erewrite seval_list_sval_refines; eauto. - + split; simpl; auto. - destruct NEST as [|st0 se lse TOP NEST]; - econstructor; simpl; auto; constructor; auto. -Qed. *) - -Definition hsexec (f: function) (pc:node): ?? hsstate := - DO path <~ some_or_fail ((fn_path f)!pc) "hsexec.internal_error.1";; - DO hinit <~ init_hsistate pc;; - DO hst <~ hsiexec_path path.(psize) f hinit;; - DO i <~ some_or_fail ((fn_code f)!(hst.(hsi_pc))) "hsexec.internal_error.2";; - DO ohst <~ hsiexec_inst i hst;; - match ohst with - | Some hst' => RET {| hinternal := hst'; hfinal := HSnone |} - | None => DO hsvf <~ hsexec_final i hst.(hsi_local);; - RET {| hinternal := hst; hfinal := hsvf |} - end. - -(** - * init_hsistate_correct_stat : OK - * init_hsistate_correct_dyn : OK - * hsexec_final_correct : OK - * hsiexec_inst_correct_dyn : TODO - * hsiexec_path_correct_dyn : TODO - * hfinal_refines_snone : OK - *) - -(* Local Hint Resolve init_hsistate_correct_stat init_hsistate_correct_dyn hsexec_final_correct - hsiexec_inst_correct_dyn hsiexec_path_correct_dyn hfinal_refines_snone: core. *) - -Lemma hsexec_correct f pc: - WHEN hsexec f pc ~> hst THEN - exists st, sexec f pc = Some st /\ hsstate_refines hst st. -Proof. Admitted. -(* unfold hsexec. intro. explore_hyp. - unfold sexec. - rewrite EQ. - exploit hsiexec_path_correct_stat; eauto. - intros (st0 & SPATH & REF0). - generalize REF0; intros (PC0 & XREF0). rewrite SPATH. - erewrite <- PC0. rewrite EQ1. - destruct (hsiexec_inst i h) eqn:HINST. - + exploit hsiexec_inst_correct_stat; eauto. - intros (st1 & EQ2 & PC2 & REF2). - - split; eauto. - - rewrite EQ2. - repeat (econstructor; simpl; eauto). - + erewrite hsiexec_inst_correct_None; eauto. - repeat (econstructor; simpl; eauto). - unfold hfinal_refines. simpl; eauto. -Qed. *) - -End CanonBuilding. - Definition simu_check_single (dm: PTree.t node) (f: RTLpath.function) (tf: RTLpath.function) (m: node * node): ?? unit := let (pc2, pc1) := m in (* creating the hash-consing tables *) @@ -2359,7 +1013,9 @@ Definition simu_check_single (dm: PTree.t node) (f: RTLpath.function) (tf: RTLpa DO hC_hsmem <~ hCons hSMEM;; let hsexec := hsexec hC_sval.(hC) hC_list_hsval.(hC) hC_hsmem.(hC) in (* performing the hash-consed executions *) + XDEBUG pc1 (fun pc => DO name_pc <~ string_of_Z (Zpos pc);; RET ("entry-point of input superblock: " +; name_pc)%string);; DO hst1 <~ hsexec f pc1;; + XDEBUG pc2 (fun pc => DO name_pc <~ string_of_Z (Zpos pc);; RET ("entry-point of output superblock: " +; name_pc)%string);; DO hst2 <~ hsexec tf pc2;; (* comparing the executions *) hsstate_simu_check dm f hst1 hst2. @@ -2367,26 +1023,6 @@ Definition simu_check_single (dm: PTree.t node) (f: RTLpath.function) (tf: RTLpa Lemma simu_check_single_correct dm tf f pc1 pc2: WHEN simu_check_single dm f tf (pc2, pc1) ~> _ THEN sexec_simu dm f tf pc1 pc2. -Proof. - unfold simu_check_single. - wlp_bind hC_sval HSVAL. wlp_bind hC_list_hsval HLSVAL. - wlp_bind hC_hsmem HSMEM. wlp_bind hst1 HSEXEC1. wlp_bind hst2 HSEXEC2. - wlp_intro u HSIMU. - unfold sexec_simu. intros st1 SEXEC. explore. - assert (TODO1: forall hs rhsv, hC hC_sval hs ~~> rhsv -> hsval_proj (hdata hs) = hsval_proj rhsv) - by admit. - assert (TODO2: forall hs rhsv, hC hC_list_hsval hs ~~> rhsv -> hsval_list_proj (hdata hs) = hsval_list_proj rhsv) - by admit. - assert (TODO3: forall hs rhsv, hC hC_hsmem hs ~~> rhsv -> hsmem_proj (hdata hs) = hsmem_proj rhsv) - by admit. - exploit hsexec_correct; eauto. - intros (st2 & SEXEC2 & REF2). - exploit hsexec_correct. 4: eapply HSEXEC1. all: eauto. - intros (st0 & SEXEC1 & REF1). - rewrite SEXEC1 in SEXEC. inv SEXEC. - eexists. split; eauto. - intros ctx. eapply hsstate_simu_check_correct in HSIMU; eauto. - eapply hsstate_simu_core_correct; eauto. Admitted. Global Opaque simu_check_single. Global Hint Resolve simu_check_single_correct: wlp. @@ -2414,7 +1050,7 @@ Global Hint Resolve simu_check_rec_correct: wlp. Definition imp_simu_check (dm: PTree.t node) (f: RTLpath.function) (tf: RTLpath.function): ?? unit := simu_check_rec dm f tf (PTree.elements dm);; - println("simu_check OK!"). + DEBUG("simu_check OK!"). Local Hint Resolve PTree.elements_correct: core. Lemma imp_simu_check_correct dm f tf: diff --git a/kvx/lib/RTLpathSE_theory.v b/kvx/lib/RTLpathSE_theory.v index 22b471fd..dd0b706e 100644 --- a/kvx/lib/RTLpathSE_theory.v +++ b/kvx/lib/RTLpathSE_theory.v @@ -469,6 +469,11 @@ Definition slocal_set_smem (st:sistate_local) (sm:smem) := Definition sist_set_local (st: sistate) (pc: node) (nxt: sistate_local): sistate := {| si_pc := pc; si_exits := st.(si_exits); si_local:= nxt |}. +Definition slocal_store st chunk addr args src : sistate_local := + let args := list_sval_inj (List.map (si_sreg st) args) in + let src := si_sreg st src in + let sm := Sstore (si_smem st) chunk addr args src + in slocal_set_smem st sm. Definition siexec_inst (i: instruction) (st: sistate): option sistate := match i with @@ -485,9 +490,7 @@ Definition siexec_inst (i: instruction) (st: sistate): option sistate := let next := slocal_set_sreg prev dst (Sload prev.(si_smem) trap chunk addr vargs) in Some (sist_set_local st pc' next) | Istore chunk addr args src pc' => - let prev := st.(si_local) in - let vargs := list_sval_inj (List.map prev.(si_sreg) args) in - let next := slocal_set_smem prev (Sstore prev.(si_smem) chunk addr vargs (prev.(si_sreg) src)) in + let next := slocal_store st.(si_local) chunk addr args src in Some (sist_set_local st pc' next) | Icond cond args ifso ifnot _ => let prev := st.(si_local) in @@ -497,7 +500,6 @@ Definition siexec_inst (i: instruction) (st: sistate): option sistate := | _ => None (* TODO jumptable ? *) end. - Lemma seval_list_sval_inj ge sp l rs0 m0 (sreg: reg -> sval) rs: (forall r : reg, seval_sval ge sp (sreg r) rs0 m0 = Some (rs # r)) -> seval_list_sval ge sp (list_sval_inj (map sreg l)) rs0 m0 = Some (rs ## l). |