(** Now the main hoare rules **)

(* Specifications: *)
Lemma hoare_frame : forall pu R c P Q F n,
hoare_ pu R P c Q n ->
hoare_ pu (fun v => R v * F) (P * F) c (Q * F) n.
Lemma hoare_skip : forall ps R Q n,
hoare_ ps R Q skip Q n.
Lemma hoare_ret : forall ps R e Q n,
hoare_ ps R
(EX v:val, eval e v && R v)
(ret e)
Q n.
Lemma hoare_call : forall ps R i f es fs Q n,
hoare_ ps R
(lift_nat (satisfies_fun_spec ps f fs) *
(EX vals:list val, list_eval es vals &&
EX a:fs_A fs,
fs_pre fs a vals *
defined i *
All v:val,
fs_post fs a v * hasval i v -* Q))
(call i f es)
Q n.
Lemma hoare_call' : forall ps R i f es fs Q,
satisfies_fun_spec ps f fs |--
hoare_ ps R
(EX vals:list val, list_eval es vals &&
EX a:fs_A fs,
fs_pre fs a vals *
defined i *
All v:val,
fs_post fs a v * hasval i v -* Q)
(call i f es)
Q.
Lemma hoare_if : forall ps R e P c1 c2 Q n,
hoare_ ps R (EX v:nat, eval e (int_val v) && !!(v <> 0) && P) c1 Q n ->
hoare_ ps R (eval e (int_val 0) && P) c2 Q n ->
hoare_ ps R
(EX v:nat, eval e (int_val v) && P)
(cif e c1 c2)
Q n.
Lemma hoare_assign : forall ps R i e Q n,
hoare_ ps R
(EX v:val, eval e v && (defined i * (hasval i v -* Q)))
(assign i e)
Q n.
Lemma hoare_store : forall ps R e1 e2 Q n,
hoare_ ps R
(EX a:addr, EX v:val,
eval e1 (ptr_val a) &&
eval e2 v &&
( (EX vold:val, mapsto a Share.top vold) *
(mapsto a Share.top v -* Q) ))
(store e1 e2)
Q n.
Lemma hoare_load : forall ps R i e Q n,
hoare_ ps R
(EX a:addr, EX sh:Share.t, EX v:val,
eval e (ptr_val a) &&
((mapsto a sh v * defined i) *
((mapsto a sh v * hasval i v) -* Q)))
(load i e)
Q n.
Lemma hoare_seq : forall ps R P1 c1 P2 c2 P3 n,
hoare_ ps R P1 c1 P2 n ->
hoare_ ps R P2 c2 P3 n ->
hoare_ ps R P1 (seq c1 c2) P3 n.
Lemma hoare_while : forall ps R e c I n,
hoare_ ps R
(EX v:nat, eval e (int_val v) && !!(v <> 0) && I)
c
(EX v:nat, eval e (int_val v) && I) n ->
hoare_ ps R
(EX v:nat, eval e (int_val v) && I)
(while e c)
(eval e (int_val 0) && I) n.
Lemma hoare_consequence : forall ps R R' P P' c Q Q' n,
hoare_ ps R P c Q n ->
lift (Q --> Q') n ->
lift (P' --> P) n ->
lift (All v:val, R v --> R' v) n ->
hoare_ ps R' P' c Q' n.
Lemma hoare_while_wp : forall ps R e c Q,
TT |-- hoare_ ps R
(EX I:pred world,
(lift_nat
(hoare_ ps R
(EX v:nat, eval e (int_val v) && !!(v <> 0) && I)
c
(EX v:nat, eval e (int_val v) && I))) *
(lift_nat (lift (eval e (int_val 0) && I --> Q))) *
(EX v:nat, eval e (int_val v) && I))
(while e c)
Q.