(** ** Definition of the variant Given a program [p] and a boolean expression [cond], the relation on environment "[reduces cond p]" is the variant required by "[synt_wp (Iwhile cond p)]".  I prove below that this relation is well-founded. *)
Definition reduces cond p e1 e0 :=
(E.eval cond e0)=true /\ (exec e0 p e1) /\ exists ef, (exec e1 (Iwhile cond p) ef).
(** To prove that "[reduces cond p]" is well-founded, I want to count the number of execution of [p] in the computation of "[Iwhile cond p]". Indeed, as the language is deterministic, this number is unique.  Hence, "[execn n e (Iwhile cond p) e']" means that "[exec e (Iwhile cond p) e']" in a sequence of [n] execution of [p]. *)
Inductive execn: nat -> E.Env -> ImpProg -> E.Env -> Prop :=
| execn_Iskip:
forall e, (execn 0 e Iskip e)
| execn_Iset:
forall (A:Type) e x (expr: E.Expr A),
(execn 0 e (Iset x expr) (E.upd x (E.eval expr e) e))
| execn_Iif:
forall n e (cond: E.Expr bool) p1 p2 e',
(execn n e (if (E.eval cond e) then p1 else p2) e')
-> (execn n e (Iif cond p1 p2) e')
| execn_Iseq:
forall n e p1 p2 e' e'',
(exec e p1 e')
-> (execn n e' p2 e'')
-> (execn n e (Iseq p1 p2) e'')
| execn_Iwhile:
forall n e cond p e',
(execn n e (Iif cond (Iseq p (Iwhile cond p)) Iskip) e')
-> (execn (S n) e (Iwhile cond p) e').
Hint Resolve execn_Iskip execn_Iset execn_Iif execn_Iseq execn_Iwhile: hoare.

(** * Completeness  The proof of completeness proceeds by induction over [prog] syntax.  *)
Lemma wp_complete: forall prog post, prog [= post =] |= (synt_wp prog post).
Hint Resolve wp_complete wp_sound: hoare.