Module HL :=  HoareLogic(Example).
(** These coercions makes the abstract syntax more user-friendly *)
Coercion getvar: ExVar >-> ExExpr.
Coercion binop: binOP >-> Funclass.
Coercion relop: relOP >-> Funclass.
(** A last coercion useful for assertions *)
Coercion get: ExVar >-> Funclass.
(** ** A [gcd] computation in this language *)
Definition gcd :=
(Iwhile (NEQ VX VY)
(Iif (LE VX VY)
(Iset VY (MINUS VY VX))
(Iset VX (MINUS VX VY)))).
Hint Resolve Zgcd_minus: zarith.
Hint Resolve Zneq_bool_true Zneq_bool_false Zle_bool_imp_le Zis_gcd_intro: zarith.
(** ** Total correctness proof of [gcd] *)
(** ** Another example: infinite loops in partial correctness.  Basic Hoare logic is not well-suited for reasoning about non-terminating programs. In total correctness, postconditions of non-terminating programs are not provable. In partial correctness, a non-terminating program satisfies any (unsatisfiable) postcondition.  For example, in an informal "meaning", the program below enumerates all multiples of 3. But this meaning can not be expressed here (even in partial correctness). *)
Definition enum_3N :=
(Iseq (Iset VX (const 0))
(Iwhile (const true)
(Iset VX (PLUS VX (const 3))))).

Lemma enum_3N_stupid:
(fun e => True) |= enum_3N  {= fun e => False =}.