Program Instance elementsUnsized {A} {def : A} (l : list A) :
Unsized (elements def l).
Next Obligation.
rewrite ! semElementsSize. by case: l.
Qed.
(* A rather long frequency proof, probably we can do better *)

(* Specifications: *)
Lemma not_lt : forall n m, (false = (n < m)) -> (m <= n).
Lemma sum_fstE A x (a : A) l:
sum_fst ((x, a) :: l) = x + sum_fst l.
Lemma sum_fst_eq0P {A} (l : list (nat * A)) :
sum_fst l = 0 <-> [seq x <- l | x.1 != 0] = [::].
Lemma pick_def :
forall {A} (l: list (nat * G A)) n def,
sum_fst l <= n ->
pick def l n = (0, def).
Lemma pick_exists :
forall {A} (l: list (nat * G A)) n def,
n <  sum_fst l <->
exists x, List.In x l /\ pick def l n = x /\ fst x <> 0.
Lemma pick_In :
forall {A} (l: list (nat * G A)) x def,
List.In x l /\ fst x <> 0 ->
exists n, pick def l n = x.
Lemma pick_imset A (def : G A) l :
pick def l @: [set m | m < sum_fst l] <--> [seq x <- l | x.1 != 0].
Lemma pickDrop_def :
forall {A} (l: list (nat * G (option A))) n,
sum_fst l <= n ->
pickDrop l n = (0, returnGen None, l).
(* Probably needs something about l' and l. *)
(* ZP : added a few things *)
Lemma pickDrop_exists :
forall {A} (l: list (nat * G (option A))) n,
n <  sum_fst l <->
exists k g l',
List.In (k,g) l /\ pickDrop l n = (k,g,l') /\ k <> 0 /\
l <--> [set (k, g)] :|: l' /\
length l' + 1 = length l /\
sum_fst l' + k = sum_fst l.
Lemma pickDrop_In :
forall {A} (l: list (nat * G (option A))) k x,
List.In (k,x) l /\ k <> 0 ->
exists n l', pickDrop l n = (k,x,l').
Lemma pickDrop_In_strong :
forall {A} (l: list (nat * G (option A))) k x,
List.In (k,x) l /\ k <> 0 ->
exists n l',
pickDrop l n = (k,x,l') /\
n < sum_fst l /\
length l = length l' + 1.
(* begin semFrequencySize *)
Lemma semFrequencySize {A}
(l : list (nat * G A)) (def : G A) (size: nat) :
semGenSize (frequency def l) size <-->
let l' := [seq x <- l | x.1 != 0] in
if l' is nil then semGenSize def size else
\bigcup_(x in l') semGenSize x.2 size.