diff options
author | Cyril SIX <cyril.six@kalray.eu> | 2020-08-21 16:56:16 +0200 |
---|---|---|
committer | Cyril SIX <cyril.six@kalray.eu> | 2020-08-21 16:56:16 +0200 |
commit | 5e47c496d7334d3a99495ddfbfcf3a8692e5b426 (patch) | |
tree | 834ade2d8e7672db72c5af6854dbdcd44ee16a51 /kvx | |
parent | 165f996be3cdf3e048fff3697ae2b69426cf70de (diff) | |
download | compcert-kvx-5e47c496d7334d3a99495ddfbfcf3a8692e5b426.tar.gz compcert-kvx-5e47c496d7334d3a99495ddfbfcf3a8692e5b426.zip |
Avancement
Diffstat (limited to 'kvx')
-rw-r--r-- | kvx/lib/RTLpathSE_impl_junk.v | 519 |
1 files changed, 508 insertions, 11 deletions
diff --git a/kvx/lib/RTLpathSE_impl_junk.v b/kvx/lib/RTLpathSE_impl_junk.v index dec7aa99..2a759ebb 100644 --- a/kvx/lib/RTLpathSE_impl_junk.v +++ b/kvx/lib/RTLpathSE_impl_junk.v @@ -600,7 +600,6 @@ Proof. - unfold hsi_sreg_eval. rewrite H. eapply hC_hsval_correct in Hexta1; [| simpl; eauto]. simpl in Hexta1. unfold seval_hsval. rewrite <- Hexta1. simpl. reflexivity. Qed. -Global Opaque hsi_sreg_get. Hint Resolve hsi_sreg_eval_correct: wlp. Definition hsok_local ge sp rs0 m0 (hst: hsistate_local) : Prop := @@ -619,11 +618,9 @@ Proof. intros H0 (H1 & _ & _). apply H1. eapply ssem_local_sok. eauto. Qed. -Definition is_subset {A: Type} (lv2 lv1: list A) := forall v, In v lv2 -> In v lv1. - Definition hsilocal_simu_core (oalive: option Regset.t) (hst1 hst2: hsistate_local) := (* is_subset (hsi_lsmem hst2) (hsi_lsmem hst1) *) - is_subset (hsi_ok_lsval hst2) (hsi_ok_lsval hst1) + 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) /\ hsi_smem hst1 = hsi_smem hst2. @@ -754,22 +751,157 @@ Proof. rewrite B; auto. Admitted. (** FIXME - requires to add some hypothesis that hsi_sreg_get may return something *) -End CanonBuilding. - Definition hsilocal_simu_check hst1 hst2 : ?? unit := phys_check (hsi_smem hst2) (hsi_smem hst1) "hsilocal_simu_check: hsi_smem sets aren't equiv";; Sets.assert_list_incl mk_hash_params (hsi_ok_lsval hst2) (hsi_ok_lsval hst1);; PTree_eq_check (hsi_sreg hst1) (hsi_sreg hst2). -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". +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. + +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. unfold hsi_sreg_get. + 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. + +(** 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_cond hext = si_cond ext + /\ 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) + /\ 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: + 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 (_ & SCOND1). rewrite <- SCOND1 by assumption. clear SCOND1. + destruct HDYN2 as (_ & SCOND2). rewrite <- SCOND2 by assumption. clear SCOND2. + destruct SIMUC as ((path & _ & LSIMU) & _ & CONDEQ & ARGSEQ). destruct LSIMU as (_ & _ & MEMEQ). + rewrite CONDEQ. rewrite ARGSEQ. rewrite MEMEQ. erewrite <- hseval_condition_preserved; eauto. + eapply ctx. } + constructor; [assumption|]. intros is1 ICONT SSEME. + assert (HOK1: hsok_exit (the_ge1 ctx) (the_sp ctx) (the_rs0 ctx) (the_m0 ctx) hse1). { + unfold hsok_exit. destruct SSEME as (_ & SSEML & _). apply ssem_local_sok in SSEML. + 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 & _ & _). + 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; [|constructor]; [congruence | eassumption | reflexivity]. + - unfold istate_simu. rewrite ICONT. + simpl. assert (PCEQ': hsi_ifso hse1 = ipc is1). { destruct HREF1 as (_ & IFSO). congruence. } + exists path. constructor; [|constructor]; [congruence | | ]. + + constructor; [|constructor]; simpl; auto. + + destruct HREF2 as (_ & IFSO). congruence. +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. + +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". + 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";; phys_check (hsi_scondargs hse1) (hsi_scondargs hse2) "hsiexit_simu_check: args do not match";; @@ -777,6 +909,37 @@ 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 @@ -786,10 +949,294 @@ 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; intros; wlp_simplify. + - destruct le2; [constructor|]. simpl in Hexta. (* Absurd case *) admit. + - destruct le2. + + (* Absurd case again *) admit. + + assert (hsiexit_simu_check dm f a h ~~> tt /\ hsiexits_simu_check dm f le1 le2 ~~> exta). { admit. } + destruct H as (A & B). apply hsiexit_simu_check_correct in A. + constructor; [assumption|]. apply IHle1 in B. assumption. +Admitted. +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). + +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). + +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. + +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) -> + all_fallthrough (the_ge2 ctx) (the_sp ctx) lse2 (the_rs0 ctx) (the_m0 ctx). +Proof. + induction 1; [unfold all_fallthrough; contradiction|]. + intros X 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. +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, + 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. destruct H as (ITAIL & ALLFU). eapply is_tail_false in ITAIL. contradiction. + - intros ext1 lx1 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; [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). 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. + + 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. 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. + +Definition hfinal_refines (hfv: hsfval) (fv: sfval) := (hfinal_proj hfv) = fv. + +Remark hfinal_refines_snone: hfinal_refines HSnone Snone. +Proof. + reflexivity. +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 hf1 f1 -> + hfinal_refines hf2 f2 -> + sfval_simu dm f opc1 opc2 ctx f1 f2. +Proof. + intros CORE FREF1 FREF2. + rewrite <- FREF1. rewrite <- FREF2. clear FREF1. clear FREF2. (* FIXME - to change when the refinement is more complex *) + destruct hf1. + (* Snone *) + - destruct hf2; try contradiction. simpl. inv CORE. constructor. assumption. + (* Scall *) + - destruct hf2; try contradiction. destruct CORE as (PCEQ & ? & ? & ? & ?). subst. + simpl. rewrite H0. rewrite H1. clear H0 H1. + constructor; [assumption | apply svident_simu_refl|]. + erewrite <- list_sval_eval_preserved; [| eapply ctx]. constructor. + (* Stailcall *) + - rewrite <- CORE. constructor; [apply svident_simu_refl|]. + erewrite <- list_sval_eval_preserved; [| eapply ctx]. constructor. + (* Sbuiltin *) + - destruct hf2; try contradiction. destruct CORE as (PCEQ & ? & ? & ?). subst. + simpl. rewrite H0. clear H0. + constructor; [assumption | reflexivity]. + (* Sjumptable *) + - destruct hf2; try contradiction. destruct CORE as (PCEQ & ?). + simpl. rewrite H. clear H. constructor; [assumption|]. + erewrite <- seval_preserved; [| eapply ctx]. constructor. + (* Sreturn *) + - destruct hf2; inv CORE. simpl. rewrite H0. constructor. +Qed. + Fixpoint revmap_check_list (dm: PTree.t node) (ln ln': list node): ?? unit := match ln, ln' with | nil, nil => RET tt @@ -827,9 +1274,9 @@ Fixpoint list_builtin_arg_simu_check lbs1 lbs2 := | _, _ => FAILWITH "list_builtin_arg_simu_check: length mismatch" end. -Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (pc1 pc2: node) (fv1 fv2: hsfval) := +Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (opc1 opc2: node) (fv1 fv2: hsfval) := match fv1, fv2 with - | HSnone, HSnone => revmap_check_single dm pc1 pc2 + | HSnone, HSnone => revmap_check_single dm opc1 opc2 | 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";; @@ -853,10 +1300,58 @@ Definition sfval_simu_check (dm: PTree.t node) (f: RTLpath.function) (pc1 pc2: n | _, _ => 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. + wlp_simplify. destruct fv1. admit. (* needs to destruct fv2 and rule out the absurd cases *) +Admitted. +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 (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|]. + 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. + +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 *) @@ -873,6 +1368,8 @@ 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. + wlp_simplify. (* TODO *) Admitted. Global Opaque simu_check_single. Global Hint Resolve simu_check_single_correct: wlp. |