Canonical Structure found_struct k := Update (found_pf k).Canonical Structure left_struct h r (f : forall k, update k r) k :=
  Update (left_pf h f k).Canonical Structure right_struct h r (f : forall k, update k r) k :=
  Update (right_pf h f k).(*********************)
(* Overloaded lemmas *)
(*********************)

Notation cont A := (ans A -> heap -> Prop).(* ret lemmas need no reflection, as they operate on any heap; still *)
(* rename them for uniformity *)

Definition val_retR := val_ret.Definition try_retR := try_ret.Definition bnd_retR := bnd_ret.Definition val_allocR := val_alloc.Definition try_allocR := try_alloc.Definition bnd_allocR := bnd_alloc.Definition val_allocbR := val_allocb.Definition try_allocbR := try_allocb.Definition bnd_allocbR := bnd_allocb.Definition val_throwR := val_throw.Definition try_throwR := try_throw.Definition bnd_throwR := bnd_throw.(****************************************************)
(* Automating the selection of which lemma to apply *)
(* (the hstep tactic made as an overloaded lemma    *)
(****************************************************)

(* Need to case-split on bnd_, try_, or a val_ lemma. *)
(* Hence, three classes of canonical structures.      *)

Structure val_form A i r (p : Prop):=
  ValForm {val_pivot :> spec A;
           _ : p -> verify val_pivot i r}.(****************************************************)
(* Automating the selection of which lemma to apply *)
(* (the hstep tactic made as an overloaded lemma    *)
(****************************************************)

(* Need to case-split on bnd_, try_, or a val_ lemma. *)
(* Hence, three classes of canonical structures.      *)

Structure val_form A i r (p : Prop):=
  ValForm {val_pivot :> spec A;
           _ : p -> verify val_pivot i r}.(****************************************************)
(* Automating the selection of which lemma to apply *)
(* (the hstep tactic made as an overloaded lemma    *)
(****************************************************)

(* Need to case-split on bnd_, try_, or a val_ lemma. *)
(* Hence, three classes of canonical structures.      *)

Structure val_form A i r (p : Prop):=
  ValForm {val_pivot :> spec A;
           _ : p -> verify val_pivot i r}.Structure bnd_form A B i (s : A -> spec B) r (p : Prop) :=
  BndForm {bnd_pivot :> spec A;
           _ : p -> verify (bind_s bnd_pivot s) i r}.Structure bnd_form A B i (s : A -> spec B) r (p : Prop) :=
  BndForm {bnd_pivot :> spec A;
           _ : p -> verify (bind_s bnd_pivot s) i r}.Structure bnd_form A B i (s : A -> spec B) r (p : Prop) :=
  BndForm {bnd_pivot :> spec A;
           _ : p -> verify (bind_s bnd_pivot s) i r}.Structure try_form A B i (s1 : A -> spec B)
                         (s2 : exn -> spec B) r (p : Prop) :=
  TryForm {try_pivot :> spec A;
           _ : p -> verify (try_s try_pivot s1 s2) i r}.Structure try_form A B i (s1 : A -> spec B)
                         (s2 : exn -> spec B) r (p : Prop) :=
  TryForm {try_pivot :> spec A;
           _ : p -> verify (try_s try_pivot s1 s2) i r}.Structure try_form A B i (s1 : A -> spec B)
                         (s2 : exn -> spec B) r (p : Prop) :=
  TryForm {try_pivot :> spec A;
           _ : p -> verify (try_s try_pivot s1 s2) i r}.Canonical Structure
  bnd_case_form A B i (s : A -> spec B) r p (e : bnd_form i s r p) :=
  ValForm (hstep_bnd e).

(* Specifications: *)
Lemma try_case_pf A B i (s1 : A -> spec B) (s2 : exn -> spec B) r p (e : try_form i s1 s2 r p) : p -> verify (try_s e s1 s2) i r.