Module HLD:=HD.
Definition sem_wp := wp.
Export Wf.
(** * Syntactic definition of the weakest precondition.  In the following, we show that this definition is logically equivalent to [wp]. *)
Fixpoint synt_wp (prog: ImpProg) : Pred -> Pred
:= fun post e =>
match prog with
| Iskip => post e
| (Iset A x expr) => post (E.upd x (E.eval expr e) e)
| (Iif cond p1 p2) =>
((E.eval cond e)=true -> (synt_wp p1 post e))
/\ ((E.eval cond e)=false -> (synt_wp p2 post e))
| (Iseq p1 p2) => synt_wp p1 (synt_wp p2 post) e
| (Iwhile cond p) =>
exists inv:Pred,
exists R:E.Env -> E.Env -> Prop,
(well_founded R)
/\ (inv e)
/\ (forall e', (inv e')
-> (E.eval cond e')=false -> post e')
/\ (forall e', (inv e')
-> (E.eval cond e')=true -> synt_wp p inv e')
/\ (forall e0, (inv e0)
-> (E.eval cond e0)=true -> synt_wp p (fun e1 => R e1 e0) e0)
end.
(** * Soundness *)
Hint Resolve synt_wp_monotonic: hoare.
(** Below, a little tactic to decompose a pair in hypothesis [H] by giving the name [n] to the first component. *)
Ltac dec2 n H := case H; clear H; intros n H.

(** The property below is also satisfied by [wp] (using the fact that the language is deterministic). We need it here to prove the soundness. *)
Lemma synt_wp_conj:
forall (p: ImpProg) (post1 post2: Pred) e,
(synt_wp p post1 e) -> (synt_wp p post2 e)
-> (synt_wp p (fun e => post1 e /\ post2 e) e).