Admitted.
(* LEO: Uh oh -- same issue *)
Fixpoint flat_map {X Y:Type} (f:X -> list Y) (l:list X)
: (list Y)
(* REPLACE THIS LINE WITH ":= _your_definition_ ." *) := [].   Definition option_map {X Y : Type} (f : X -> Y) (xo : option X) : option Y := match xo with | None => None | Some x => Some (f x) end.   Fixpoint fold {X Y:Type} (f: X->Y->Y) (l:list X) (b:Y) : Y := match l with | nil => b | h :: t => f h (fold f t b) end.   Definition constfun {X: Type} (x: X) : nat->X := fun (k:nat) => x.  Definition ftrue := constfun true.  Definition fold_length {X : Type} (l : list X) : nat := fold (fun _ n => S n) l 0.  Definition fold_length_correctP := fun X (l : list X) => (fold_length l = length (l++l))?. (*! QuickCheck fold_length_correctP. *)
Definition fold_length_correctP_bad := fun X (l : list X) =>
(fold_length l = length (l++l))?.
QuickCheck (expectFailure fold_length_correctP).
Definition fold_map {X Y:Type} (f : X -> Y) (l : list X) : list Y
(* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.  (** Write down a theorem [fold_map_correct] in Coq stating that [fold_map] is correct, and prove it. *)
(* LEO: ... :-? *)
Definition prod_curry {X Y Z : Type}
(f : X * Y -> Z) (x : X) (y : Y) : Z := f (x, y).
(** As an exercise, define its inverse, [prod_uncurry].  Then prove the theorems below to show that the two are inverses. *)
Definition prod_uncurry {X Y Z : Type}
(f : X -> Y -> Z) (p : X * Y) : Z
(* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.  (** As a (trivial) example of the usefulness of currying, we can use it to shorten one of the examples that we saw above: *)
(* LEO: Getting even more challenging... *)

Theorem uncurry_curry : forall (X Y Z : Type)
(f : X -> Y -> Z)
x y,
prod_curry (prod_uncurry f) x y = f x y.