Library multi_zero_s_simu
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq.
Require Import Init_ext ZArith_ext seq_ext uniq_tac.
Require Import machine_int multi_int encode_decode integral_type.
Import MachineInt.
Require Import mips_bipl mips_cmd mips_tactics mips_syntax mips_mint.
Import mips_bipl.expr_m.
Require Import simu.
Import simu.simu_m.
Require Import multi_zero_s_prg multi_zero_s_triple.
Local Open Scope heap_scope.
Local Open Scope assoc_scope.
Local Open Scope uniq_scope.
Local Open Scope machine_int_scope.
Local Open Scope zarith_ext_scope.
Local Open Scope asm_expr_scope.
Local Open Scope simu_scope.
Require Import Init_ext ZArith_ext seq_ext uniq_tac.
Require Import machine_int multi_int encode_decode integral_type.
Import MachineInt.
Require Import mips_bipl mips_cmd mips_tactics mips_syntax mips_mint.
Import mips_bipl.expr_m.
Require Import simu.
Import simu.simu_m.
Require Import multi_zero_s_prg multi_zero_s_triple.
Local Open Scope heap_scope.
Local Open Scope assoc_scope.
Local Open Scope uniq_scope.
Local Open Scope machine_int_scope.
Local Open Scope zarith_ext_scope.
Local Open Scope asm_expr_scope.
Local Open Scope simu_scope.
x <- 0, x signed
Lemma pfwd_sim_zero_s P (x : bipl.var.v) d k rx :
uniq(rx, r0) -> x \notin assoc.dom d ->
signed k rx \notin (assoc.cdom d) ->
(x <- nat_e O)%pseudo_expr%pseudo_cmd
<=p(state_mint (x |=> signed k rx \U+ d), P)
multi_zero_s rx.
Proof.
move=> Hnodup x_d rx_d.
move=> s st h [s_st_h HP] s' exec_pseudo st' h' exec_asm.
move: (state_mint_var_mint _ _ _ _ x (signed k rx) s_st_h).
rewrite assoc.get_union_sing_eq.
move/(_ refl_equal).
case=> slen ptr A rx_fit [len_A slen_k slen_x x_A] ptr_fit Hmem.
move: (multi_zero_s_triple _ Hnodup A ).
move/(_ ptr slen) => Hhoare_triple.
have [st'' [h'' Hexec_triple_proj]] : exists st'' h'',
(Some (st, heap.proj h (heap.dom (heap_mint (signed k rx) st h))) --
multi_zero_s rx ---> Some (st'', h''))%mips_cmd.
exists st', (heap.proj h' (heap.dom (heap_mint (signed k rx) st h))).
apply (mips_syntax.triple_exec_proj _ _ _ Hhoare_triple) => //.
suff : h |P| heap.dom (heap_mint (signed k rx) st h) = heap_mint (signed k rx) st h by move=> ->.
by apply heap.incluE, heap_inclu_heap_mint_signed.
set postcond := (_ |--> zero32 :: _ ** _)%asm_assert in Hhoare_triple.
have {Hhoare_triple}Hhoare_triple_post_condition : ((postcond ** assert_m.TT) st' h')%asm_assert.
move/mips_seplog.hoare_prop_m.soundness: (mips_frame.frame_rule_R _ _ _ Hhoare_triple assert_m.TT (assert_m.inde_TT _) (mips_frame.inde_cmd_mult_TT _)).
rewrite /while.hoare_semantics.
move/(_ st h) => Hhoare_triple_sem.
lapply Hhoare_triple_sem; last first.
exists (heap_mint (signed k rx) st h), (h \D\ heap.dom (heap_mint (signed k rx) st h)).
split; first by apply heap.disj_difs', seq_ext.inc_refl.
split.
apply heap.union_difsK => //; exact/heap_inclu_heap_mint_signed.
split; last by [].
exact Hmem.
move=> {Hhoare_triple_sem}[Hhoare_triple_sem Hhoare_triple_sem'].
by apply Hhoare_triple_sem' in exec_asm.
have rx_st_st' : [ rx ]_ st = [ rx ]_ st'.
mips_syntax.Reg_unchanged; simpl mips_frame.modified_regs; by Uniq_not_In.
rewrite /state_mint; split.
- move=> y my.
case/assoc.get_union_Some_inv => y_my.
+ case/assoc.get_sing_inv : y_my => ? ?; subst y my.
move/syntax_m.seplog_m.semop_prop_m.exec_cmd0_inv : exec_pseudo.
case/syntax_m.seplog_m.exec0_assign_inv => _ Hs'.
apply mkVarSigned with zero32 ptr A => //.
* by rewrite -rx_st_st'.
* apply mkSignMagn => //.
- rewrite s2Z_u2Z_pos' //; by rewrite Z2uK.
- rewrite Hs'.
syntax_m.seplog_m.assert_m.expr_m.Store_upd.
rewrite s2Z_u2Z_pos' //; by rewrite Z2uK.
- rewrite Hs'.
syntax_m.seplog_m.assert_m.expr_m.Store_upd.
rewrite s2Z_u2Z_pos' //; by rewrite Z2uK.
case: Hhoare_triple_post_condition => [h1 [h2 [h1_d_h2 [h1_U_h2 [Hh1 Hh2]]]]].
apply con_heap_mint_signed_cons with h1 => //.
- rewrite h1_U_h2.
apply heap.inclu_union_L => //.
by apply heap.inclu_refl.
- by rewrite -rx_st_st'.
- by rewrite len_A.
+ have y_x : y <> x.
move=> ?; subst y.
apply assoc.get_Some_in_dom in y_my.
by rewrite y_my in x_d.
apply var_mint_invariant with s st.
* move=> rx0 Hrx0.
Reg_unchanged.
rewrite [mips_frame.modified_regs _]/=.
by auto.
* Var_unchanged. rewrite /= mem_seq1; exact/negP/eqP.
* suff : heap_mint my st' h' = heap_mint my st h.
move=> ->.
apply (state_mint_var_mint _ _ _ _ _ _ s_st_h).
by rewrite assoc.get_union_sing_neq.
symmetry.
move: (proj2 s_st_h _ _ y_x my (signed k rx)).
rewrite assoc.get_union_sing_neq // assoc.get_union_sing_eq.
move/(_ y_my (refl_equal _)) => heap_mint_disj.
case: (mips_syntax.exec_deter_proj _ _ _ _ _ exec_asm _ _ _ Hexec_triple_proj)
=> st'_st'' [h''_h' h_h'_dif].
apply (heap_mint_state_invariant (heap_mint (signed k rx) st h) y s) => //.
- move=> rx0 Hrx0; Reg_unchanged.
apply (@disj_not_In _ (mint_regs my)); last by [].
have Hd_unchanged : forall v r, assoc.get v d = Some r ->
disj (mint_regs r) (mips_frame.modified_regs (multi_zero_s rx)).
move=> v r Hvr; rewrite [mips_frame.modified_regs _]/=; by apply disj_nil_R.
rewrite [mips_frame.modified_regs _]/=; exact/disj_nil_L.
- apply (state_mint_var_mint _ _ _ _ _ _ s_st_h).
by rewrite assoc.get_union_sing_neq.
- have Hdom : heap.dom (heap_mint (signed k rx) st' h') = heap.dom (heap_mint (signed k rx) st h).
symmetry.
case: Hhoare_triple_post_condition => [h1 [h2 [h1_d_h2 [h1_U_h2 [Hh1 Hh2]]]]].
apply dom_heap_mint_sign_state_invariant with x s slen zero32 => //.
- apply assert_m.mapstos_get1 in Hmem.
by apply heap_get_heap_mint_inv in Hmem.
- apply assert_m.mapstos_get1 in Hh1.
rewrite h1_U_h2.
by apply heap.get_union_L.
- move/assert_m.mapstos_get2 : Hmem.
move/heap_get_heap_mint_inv => ->.
symmetry.
rewrite h1_U_h2.
apply heap.get_union_L => //.
by apply assert_m.mapstos_get2 in Hh1.
- apply mkVarSigned with slen ptr A => //.
by eapply dom_heap_invariant; eauto.
apply (state_mint_part2_one_variable _ _ _ _ _ _ _ _ s_st_h Hdom).
+ move=> t x0 Ht Hx0.
Reg_unchanged. simpl mips_frame.modified_regs.
by auto.
+ move: (mips_syntax.exec_deter_proj _ _ _ _ _ exec_asm _ _ _ Hexec_triple_proj); tauto.
+ by apply (mips_syntax.dom_heap_invariant _ _ _ _ _ exec_asm).
Qed.