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_true:
forall e cond p1 p2 e',
(E.eval cond e)=true
-> (exec e p1 e')
-> (exec e (Iif cond p1 p2) e').