(* Hoare Logic *)
Inductive immed_safe: state -> Prop :=
| IS_stop: forall rho m, immed_safe (State rho m Cskip)
| IS_step: forall s s', step s s' -> immed_safe s.
Definition safe (s: state) : Prop :=
forall s', stepstar s s' -> immed_safe s'.
Definition guard (P: h_assert) (c: command) :=
forall rho,   P rho -> safe (State rho m0 c).
Definition Hoare (P: h_assert) (c: command) (Q: h_assert) : Prop :=
forall k, guard Q k -> guard P (Cseq c k).
Definition subst (x:var) (v: option val) (P: h_assert) : h_assert :=
fun rho => P (upd rho x v).

(* Specifications: *)
Lemma safe_step: forall s s',
step s s' -> safe s' -> safe s.
Lemma upd_same: forall A B {EA: EqDec A} rho (x: A) (v: option B), upd rho x v x = v.
Lemma upd_other: forall A B {EA: EqDec A} rho (x y: A) (v: option B),
x <> y -> upd rho x v y = rho y.
Lemma floyd_assign:
forall (P: h_assert) (x: var) (e: expr),
(forall rho, P rho -> exists v, eval e v rho) ->
Hoare P (Cassign x e)
(fun rho => exists v, exists x',
eval (Evar x) v rho /\ subst x x' (eval e v) rho /\ subst x x' P rho).