Program Instance liftGen2Monotonic {A1 A2 B} (f : A1 -> A2 -> B) (g1 : G A1)
`{SizeMonotonic _ g1} (g2 : G A2) `{SizeMonotonic _ g2} :
SizeMonotonic (liftGen2 f g1 g2).
Next Obligation.
rewrite ! semLiftGen2Size. rewrite ! curry_imset2l.
move => b [a1 [Ha1 [a2 [Ha2 <-]]]].
do 2 (eexists; split; first by eapply (monotonic H1); eauto).
reflexivity.
Qed.

(* Specifications: *)
(* CH: Made this more beautiful than the rest *)
(* CH: Should anyway use dependent types for a generic liftGenN *)
Lemma semLiftGen4Size A1 A2 A3 A4 B (f : A1 -> A2 -> A3 -> A4 -> B)
(g1 : G A1) (g2 : G A2) (g3 : G A3) (g4 : G A4) s :
semGenSize (liftGen4 f g1 g2 g3 g4) s <-->
[set b : B | exists a1 a2 a3 a4, semGenSize g1 s a1 /\ semGenSize g2 s a2 /\
semGenSize g3 s a3 /\ semGenSize g4 s a4 /\ f a1 a2 a3 a4 = b].
(* begin semLiftGen4SizeMonotonic *)
Lemma semLiftGen4SizeMonotonic A1 A2 A3 A4 B (f : A1 -> A2 -> A3 -> A4 -> B)
(g1 : G A1) (g2 : G A2) (g3 : G A3) (g4 : G A4)
`{SizeMonotonic _ g1} `{SizeMonotonic _ g2}
`{SizeMonotonic _ g3} `{SizeMonotonic _ g4} :
semGen (liftGen4 f g1 g2 g3 g4) <-->
[set b : B | exists a1 a2 a3 a4, semGen g1 a1 /\ semGen g2 a2 /\
semGen g3 a3 /\ semGen g4 a4 /\ f a1 a2 a3 a4 = b].