(* end semLiftGen4SizeMonotonic *)
Program Instance liftGen4Monotonic {A B C D E}
(f : A -> B -> C -> D -> E)
(g1 : G A) (g2 : G B) (g3 : G C) (g4 : G D)
`{ SizeMonotonic _ g1} `{ SizeMonotonic _ g2}
`{ SizeMonotonic _ g3} `{ SizeMonotonic _ g4}
: SizeMonotonic (liftGen4 f g1 g2 g3 g4).
Next Obligation.
rewrite ! semLiftGen4Size.
move => t /= [a1 [a2 [a3 [a4 [Ha1 [Ha2 [Ha3 [Ha4 H5]]]]]]]]; subst.
eexists. eexists. eexists. eexists.
repeat (split; try reflexivity); by eapply monotonic; eauto.
Qed.

(* Specifications: *)
Lemma semLiftGen5Size :
forall {A1 A2 A3 A4 A5 B} (f: A1 -> A2 -> A3 -> A4 -> A5 -> B)
(g1: G A1) (g2: G A2) (g3: G A3) (g4: G A4) (g5: G A5) size,
semGenSize (liftGen5 f g1 g2 g3 g4 g5) size <-->
fun b =>
exists a1, semGenSize g1 size a1 /\
(exists a2, semGenSize g2 size a2 /\
(exists a3, semGenSize g3 size a3 /\
(exists a4, semGenSize g4 size a4 /\
(exists a5, semGenSize g5 size a5 /\
(f a1 a2 a3 a4 a5) = b)))).
Lemma semSequenceGenSize A (gs : list (G A)) n :
semGenSize (sequenceGen gs) n <-->
[set l | length l = length gs /\
List.Forall2 (fun y => semGenSize y n) gs l].
Lemma Forall2_SizeMonotonic {A} x n (gs : list (G A)) l :
x <= n -> gs \subset SizeMonotonic ->
List.Forall2 (semGenSize^~ x) gs l ->
List.Forall2 (semGenSize^~ n) gs l.
Lemma semSequenceGenSizeMonotonic A (gs : list (G A)) :
(gs \subset SizeMonotonic) ->
semGen (sequenceGen gs) <-->
[set l | length l = length gs /\
List.Forall2 semGen gs l].
Lemma semVectorOfSize {A : Type} (k : nat) (g : G A) n :
semGenSize (vectorOf k g) n <-->
[set l | length l = k /\ l \subset (semGenSize g n)].
Lemma semVectorOfUnsized {A} (g : G A) (k : nat) `{Unsized _ g}:
semGen (vectorOf k g) <--> [set l | length l = k /\ l \subset semGen g ].