Definition do' : STsep s2 := Model.Do e doP.Notation "'Do' e" := (do' e _) (at level 80).Definition read : STsep read_s := Model.Do (Model.read A x) readP.Definition write : STsep write_s := Model.Do (Model.write x v) writeP.Definition alloc : STsep alloc_s := Model.Do (Model.alloc v) allocP.Definition allocb_s : spec ptr :=
  (emp, fun y i m => exists x:ptr, y = Val x /\ m = updi x (nseq n v)).Definition allocb : STsep allocb_s := Model.Do (Model.allocb v n) allocbP.Definition dealloc : STsep dealloc_s := Model.Do (Model.dealloc x) deallocP.Definition throw_s : spec A :=
  (emp, fun y i m => m = i /\ y = Exn e).Definition throw : STsep throw_s := Model.Do (Model.throw A e) throwP.Definition try : STsep try_s := Model.Do (Model.try e e1 e2) tryP.Notation tp := (forall x, STsep (s x)).Definition Fix (f : tp -> tp) : tp := Model.ffix f.Program
Definition If (e1 : STsep s1) (e2 : STsep s2) : STsep (if b then s1 else s2) :=
  match b with true => Do e1 | false => Do e2 end.Program
Definition Match_opt (e1 : STsep s1) (e2 : forall v, STsep (s2 v)) :
             STsep (match x with Some v => s2 v | None => s1 end) :=
  match x with Some v => Do (e2 v) | None => Do e1 end.Program
Definition Match_dec (e1 : forall x, STsep (s1 x))
                     (e2 : forall x, STsep (s2 x)) :
             STsep (match b with left x => s1 x | right x => s2 x end) :=
  match b with left x => Do (e1 x) | right x => Do (e2 x) end.

Lemma ghE (B : Type) (q : heap -> B -> Prop) (r : B -> post A) : (forall i, p i -> def i -> exists x, q i x) -> (forall i x, q i x -> p i -> def i -> verify s i (fun y m => r x y i m)) -> conseq s p (fun y i m => forall x, q i x -> r x y i m).