Module QcDoNotation.
Notation "'do!' X <- A ; B" :=
(bindGen A (fun X => B))
(at level 200, X ident, A at level 100, B at level 200).
Notation "'doM!' X <- A ; B" :=
(bindGenOpt A (fun X => B))
(at level 200, X ident, A at level 100, B at level 200).
End QcDoNotation.
(* CH: Reusing :: instead of ;; would have been nice, but I didn't manage *)
Instance bindOptMonotonicOpt
{A B} (g : G (option A)) (f : A -> G (option B))
`{SizeMonotonicOpt _ g} `{forall x, SizeMonotonicOpt (f x)} :
SizeMonotonicOpt (bindGenOpt g f).
Instance bindOptMonotonic
{A B} (g : G (option A)) (f : A -> G (option B))
`{SizeMonotonic _ g} `{forall x, SizeMonotonic (f x)} :
SizeMonotonic (bindGenOpt g f).

Lemma semBindOptSizeMonotonicIncl_l {A B} (g : G (option A)) (f : A -> G (option B)) (s1 : set A)
(fs : A -> set B)
`{Hg : SizeMonotonicOpt _ g}
`{Hf : forall a, SizeMonotonicOpt (f a)} :
Some @: s1 \subset semGen g ->
(forall x, Some @: (fs x) \subset semGen (f x)) ->
(Some @: \bigcup_(a in s1) (fs a)) \subset semGen (bindGenOpt g f).