End Bind.
Section Try.
Variables (A B : Type) (s : spec A) (s1 : A -> spec B) (s2 : exn -> spec B).
Variables (e : ST s) (e1 : forall x, ST (s1 x)) (e2 : forall x, ST (s2 x)).
Definition try_pre : pre :=
fun i => s.1 i /\ (forall y m, s.2 (Val y) i m -> (s1 y).1 m) /\
forall e m, s.2 (Exn e) i m -> (s2 e).1 m.
Definition try_post : post B :=
fun y i m => (exists x, exists h, s.2 (Val x) i h /\ (s1 x).2 y h m) \/
(exists e, exists h, s.2 (Exn e) i h /\ (s2 e).2 y h m).
Definition try_s := (try_pre, try_post).
Definition try_sp (p : ideald try_s.1) y m :=
exists i, exists x, exists h, i \In id_val p /\
(i, x, h) \In runs_of (model e) /\
match x with
Val x' => (h, y, m) \In runs_of (model (e1 x'))
| Exn e => (h, y, m) \In runs_of (model (e2 e))
end.

(* Specifications: *)
Lemma try_coherent : coherent try_sp.
Lemma try_dstrict : def_strict try_sp.
Lemma try_has_spec : try_sp \In has_spec try_s.
Definition try := STprog try_coherent try_dstrict try_has_spec.