(**  This file is part of the "Tutorial on Hoare Logic". For an introduction to this Coq library, see README #or <a href=index.html>index.html</a>#.  This file is mainly verbous. It defines a functor "[HoareLogic: ExprLang -> HoareLogicSem]". It is almost a copy/paste of definitions found in #<a href=hoarelogicsemantics.html># [hoarelogicsemantics]#</a>#. (This is due to the lack of inheritance in the module system of Coq).   *)
Set Implicit Arguments.
Require Export hoarelogicsemantics.
Module HoareLogic(Ex: ExprLang)<: HoareLogicSem with Module E:=Ex.
Module E:=Ex.
Module HLD <: HoareLogicDefs with Module E:=E.
Module E:=E.
Inductive ImpProg: Type :=
| Iskip: ImpProg
| Iset (A:Type) (v:E.Var A) (expr:E.Expr A): ImpProg
| Iif (cond:E.Expr bool) (p1 p2:ImpProg): ImpProg
| Iseq (p1 p2:ImpProg): ImpProg
| Iwhile (cond:E.Expr bool) (p:ImpProg): ImpProg.
Inductive exec: E.Env -> ImpProg -> E.Env -> Prop :=
| exec_Iskip:
forall e, (exec e Iskip e)
| exec_Iset:
forall (A:Type) e x (expr: E.Expr A),
(exec e (Iset x expr) (E.upd x (E.eval expr e) e))
| exec_Iif:
forall e (cond: E.Expr bool) p1 p2 e',
(exec e (if (E.eval cond e) then p1 else p2) e')
-> (exec e (Iif cond p1 p2) e')
| exec_Iseq:
forall e p1 p2 e' e'',
(exec e p1 e')
-> (exec e' p2 e'')
-> (exec e (Iseq p1 p2) e'')
| exec_Iwhile:
forall e cond p e',
(exec e (Iif cond (Iseq p (Iwhile cond p)) Iskip) e')
-> (exec e (Iwhile cond p) e').

Lemma exec_Iif_false:
forall e cond p1 p2 e',
(E.eval cond e)=false
-> (exec e p2 e')
-> (exec e (Iif cond p1 p2) e').