End SepTry.
Section SepFix.
Variables (A : Type) (B : A -> Type) (s : forall x, spec (B x)).
Notation tp := (forall x, STsep (s x)).
Definition Fix (f : tp -> tp) : tp := Model.ffix f.
End SepFix.
(* Conditionals for various types *)
Section CondBool.
Variables (A : Type) (b : bool) (s1 s2 : spec A).
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.
End CondBool.
Section CondOption.
Variable (A B : Type) (x : option A) (s1 : spec B) (s2 : A -> spec B).
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.
End CondOption.
Section CondDecide.
Variable (A : Type) (p1 p2 : Prop) (b : {p1} + {p2})
(s1 : p1 -> spec A) (s2 : p2 -> spec A).
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.
End CondDecide.
Section CondNat.
Variable (A : Type) (n : nat) (s1 : spec A) (s2 : nat -> spec A).
Program
Definition Match_nat (e1 : STsep s1) (e2 : forall n, STsep (s2 n)) :
STsep (match n with 0 => s1 | m.+1 => s2 m end) :=
match n with 0 => Do e1 | m.+1 => Do (e2 m) end.
End CondNat.
Section CondSeq.
Variable (A B : Type) (s : seq A) (s1 : spec B) (s2 : A -> seq A -> spec B).
Program
Definition Match_seq (e1 : STsep s1) (e2 : forall hd tl, STsep (s2 hd tl)) :
STsep (match s with [::] => s1 | hd::tl => s2 hd tl end) :=
match s with [::] => Do e1 | hd::tl => Do (e2 hd tl) end.
End CondSeq.
(******************************************)
(* Lemmas for pulling out ghost variables *)
(******************************************)
Section Ghosts.
Variables (A : Type) (s : spec A) (p : pre).

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).