(* foldBody_option is an adapter that allows you to fold a computation with signature B -> A -> Comp (option B) over a list of A, accumulating an option B. *)
Definition foldBody_option(A B : Set)(eqd : EqDec B)(f : B -> A -> Comp (option B))(b_opt : option B)(a : A) :=
  match b_opt with
      | None => ret None
      | Some b =>
        f b a
  end.Definition opt_pred(A B : Set)(P : A -> B -> Prop)(opt_a : option A)(opt_b : option B) :=
  match opt_a with
    | Some a =>
      match opt_b with
        | Some b => P a b
        | None => False
      end
    | None =>
      match opt_b with
        | Some _ => False
        | None => True
      end
  end.

(* Specifications: *)
Theorem foldBody_option_spec : forall (A B C D: Set)(eqda : EqDec A)(eqdb : EqDec B) (c1 : A -> C -> Comp (option A)) (c2 : B -> D -> Comp (option B)) (post : A -> B -> Prop) (pre1 : A -> B -> Prop) (pre2 : C -> D -> Prop), (forall a b c d, pre1 a b -> pre2 c d -> comp_spec (opt_pred post) (c1 a c) (c2 b d)) -> forall opt_a opt_b c d, opt_pred pre1 opt_a opt_b -> pre2 c d -> comp_spec (opt_pred post) (foldBody_option _ c1 opt_a c) (foldBody_option _ c2 opt_b d).
Theorem compFold_option_spec : forall (A B : Set)(lsa : list A)(lsb : list B)(pre : A -> B -> Prop), list_pred pre lsa lsb -> forall (C D : Set){eqdc : EqDec C}{eqdd : EqDec D}(c1 : C -> A -> Comp (option C))(c2 : D -> B -> Comp (option D))(post : C -> D -> Prop) c d, (forall c d a b, post c d -> pre a b -> comp_spec (opt_pred post) (c1 c a) (c2 d b)) -> opt_pred post c d -> comp_spec (opt_pred post) (compFold _ (foldBody_option _ c1) c lsa) (compFold _ (foldBody_option _ c2) d lsb).
Theorem compMap_nil : forall (A B : Set)(eqdb : EqDec B)(c : A -> Comp B), compMap _ c nil = ret nil.
Theorem list_inhabited : forall (A : Set), list A.