Section PWO_Seq.
Variable D1 R1 DO RO : Set.
Variable (PWO_P1 : ProcedureWithOracle D1 R1 DO RO).
Variable R2 : Set.
Variable (PWO_P2 : ProcedureWithOracle R1 R2 DO RO).
Hint Resolve (PWO_P1.(S_P_EqDec)) : typeclass_instances.
Hint Resolve (PWO_P2.(S_P_EqDec)) : typeclass_instances.
Hint Resolve (PWO_P1.(D_O_EqDec)) : typeclass_instances.
Hint Resolve (PWO_P2.(R_P_EqDec)) : typeclass_instances.
Definition S_P' := (nat * (PWO_P1.(S_P) + PWO_P2.(S_P))).
Definition PWO_Seq_P1 (d : D1) : Comp (DO * S_P') :=
[d, s] <-$2 PWO_P1.(P1) d;
ret (d, (PWO_P1.(q), inl s)).
intuition.
unfold PWO_Seq_P1.
wftac.
eapply P1_wf.
Qed.
Definition PWO_Seq_P2 (s : S_P') (r : RO)  : Comp (DO * S_P') :=
match (snd s) with
| inl s' =>
match (fst s) with
| O =>
r <-$ P3 s' r;
[d', s'] <-$2 PWO_P2.(P1) r;
ret (d', (O, inr s'))
| S q' =>
[d', s'] <-$2 P2 s' r;
ret (d', (q', inl s'))
end
| inr s' =>
[d', s'] <-$2 P2 s' r;
ret (d', (O, inr s'))
end.
intuition.
unfold PWO_Seq_P2.
destruct (snd x); destruct (fst x); wftac.
eapply P3_wf.
eapply P1_wf.
eapply P2_wf.
eapply P2_wf.
eapply P2_wf.
Qed.
Variable R2_def : R2.
Definition PWO_Seq_P3 (s : S_P') r : Comp R2 :=
match (snd s) return (Comp R2) with
| inl s' => ret R2_def
| inr s' => P3 s' r
end.

Theorem PWO_Seq_P3_wf :
forall x y,
well_formed_comp (PWO_Seq_P3 x y).