Library tactics
From mathcomp Require Import ssreflect eqtype ssrbool seq.
Require Import bipl seplog integral_type seq_ext ZArith.
Declare Scope tactics_scope.
Local Open Scope Z_scope.
Require Import bipl seplog integral_type seq_ext ZArith.
Declare Scope tactics_scope.
Local Open Scope Z_scope.
Preliminary tests before implementing seplog tactics
Module Tactics (A : IntegralType).
Module Import seplog_m := Seplog A.
Import seplog_m.assert_m.expr_m.
Import seplog_m.assert_m.
Local Open Scope Z_scope.
Local Open Scope seplog_expr_scope.
Local Open Scope seplog_cmd_scope.
Local Open Scope seplog_assert_scope.
Local Open Scope seplog_hoare_scope.
Definition pure (e : expr_b) : assert := fun s h => h = heap.emp /\ eval_b e s = true.
Notation "! e" := (pure e) (at level 80) : tactics_scope.
Local Open Scope tactics_scope.
Lemma hoare_drop_pure : forall P c Q e, {{ P }} c {{ Q }} -> {{ P ** ! e }} c {{ Q }}.
Proof.
move=> P c Q e H.
apply hoare_prop_m.hoare_stren with P => //.
move=> s h [h1 [h2 [Hdisj [Hunion [HP [Hh2 He]]]]]].
subst h2.
by rewrite Hunion heap.unionhe.
Qed.
Lemma hoare_assign_forward P v e :
inde (v :: nil) P -> disj (vars e) (v :: nil) ->
{{ P }} v <- e {{ P ** ! (var_e v \= e ) }}.
Proof.
move=> Hinde Hinter.
apply hoare_assign' => s h HP.
exists h, heap.emp.
split; first exact: heap.disjhe.
split; first by rewrite heap.unionhe.
split; first exact: inde_upd_store.
split; first by [].
rewrite /= store.get_upd' eval_upd; first exact/A.eqP.
apply/negP/inP; eapply disj_not_In; eauto.
by rewrite /=; auto.
Qed.
Lemma hoare_assign_lookup_forward e1 e2 v :
disj (vars e1) (v :: nil) ->
seq_ext.disj (vars e2) (v :: nil) ->
{{ e1 |~> e2 }} v <-* e1 {{ e1 |~> e2 ** ! (var_e v \= e2) }}.
Proof.
move=> He1 He2.
apply hoare_lookup' => s h [p [Hp Hh]].
exists ([ e2 ]e_s).
split; first by rewrite Hh Hp heap.get_sing.
exists h; exists heap.emp.
split; first by apply heap.disjhe.
split; first by rewrite heap.unionhe.
split.
exists p.
split.
rewrite eval_upd //.
apply/negP/inP; eapply disj_not_In; eauto.
by rewrite /=; auto.
rewrite eval_upd //.
apply/negP/inP; eapply disj_not_In; eauto.
by rewrite /=; auto.
split; first by [].
rewrite /= store.get_upd' eval_upd; first exact/A.eqP.
apply/negP/inP; eapply disj_not_In; eauto.
by rewrite /=; auto.
Qed.
Ltac Inde :=
match goal with
| |- inde _ TT =>
apply inde_TT
| |- inde _ (_ |~> _) =>
apply inde_mapsto; [idtac | idtac]
| |- _ =>
fail "Inde: not supported"
end.
Ltac forward1 :=
match goal with
| |- {{ ?P }} cmd_cmd0_coercion_redefined (?x <- ?e) {{ ?P ** ! (var_e ?x \= ?e )}} =>
apply hoare_assign_forward; [Inde | idtac ]
| |- {{ ?e |~> ?e' }} cmd_cmd0_coercion_redefined (?x <-* ?e) {{ ?e |~> ?e' ** ! (var_e ?x \= ?e') }} =>
apply hoare_assign_lookup_forward; [idtac | idtac]
| _ =>
fail "forward1: not supported"
end.
Ltac forward :=
match goal with
| |- hoare_m.hoare _ _ _ =>
rewrite /hoare_m.hoare /hoare_m.store /hoare_m.heap
/hoare_m.cmd0 /hoare_m.expr_b /hoare_m.eval_b /hoare_m.hoare0
| _ => idtac
end ;
match goal with
| |- {{ _ }} (_ ; _ ) ; _ {{ _ }} =>
apply hoare_prop_m.hoare_seq_assoc; forward
| |- {{ ?P }} cmd_cmd0_coercion_redefined (?x <- ?e) ; _ {{ _ }} =>
apply while.hoare_seq with (P ** ! (var_e x \= e)); [forward1 | idtac]
| |- {{ ?e |~> ?e' }} cmd_cmd0_coercion_redefined (?x <-* ?e) ; _ {{ _ }} =>
apply while.hoare_seq with (e |~> e' ** ! (var_e x \= e')); [forward1 | idtac]
| |- _ =>
fail "forward: not supported"
end.
End Tactics.
Module Import tactics_m := Tactics ZIT.
Import seplog_m.
Import seplog_m.assert_m.expr_m.
Import seplog_m.assert_m.
Local Open Scope Z_scope.
Local Open Scope seplog_expr_scope.
Local Open Scope seplog_cmd_scope.
Local Open Scope seplog_assert_scope.
Local Open Scope seplog_hoare_scope.
Local Open Scope tactics_scope.
Lemma test0 : {{ TT }} O <- cst_e 1 {{ TT ** ! (var_e O \= cst_e 1) }}.
Proof. forward1. by apply disj_nil_L. Qed.
Lemma test1 : {{ cst_e 1 |~> cst_e 2 }} O <-* cst_e 1 {{ cst_e 1 |~> cst_e 2 ** ! (var_e O \= cst_e 2) }}.
Proof. forward1. by apply disj_nil_L. by apply disj_nil_L. Qed.
Lemma test2 :
{{ cst_e 1 |~> cst_e 2 }}
O <- cst_e 1 ; O <-* cst_e 1
{{ cst_e 1 |~> cst_e 2 ** ! (var_e O \= cst_e 2) }}.
Proof.
forward.
exact: disj_nil_L.
exact: disj_nil_L.
exact: disj_nil_L.
apply hoare_drop_pure.
forward1.
exact: disj_nil_L.
exact: disj_nil_L.
Qed.
Lemma test3 :
{{ cst_e 1 |~> cst_e 2 }}
(O <- cst_e 1 ; O <-* cst_e 1) ; O <- cst_e 3
{{ cst_e 1 |~> cst_e 2 ** ! (var_e O \= cst_e 3) }}.
Proof.
forward.
exact/disj_nil_L.
exact/disj_nil_L.
exact/disj_nil_L.
apply hoare_drop_pure.
forward.
exact/disj_nil_L.
exact/disj_nil_L.
apply hoare_drop_pure.
forward1.
exact/disj_nil_L.
exact/disj_nil_L.
exact/disj_nil_L.
Qed.