Fixpoint BDDneg_1 (cfg : BDDconfig) (ul : list ad) 
 (node : ad) (bound : nat) {struct bound} : BDDconfig * ad :=
  match bound with
  | O => (* Error *)  (initBDDconfig, BDDzero)
  | S bound' =>
      match MapGet _ (negm_of_cfg cfg) node with
      | Some node' => (cfg, node')
      | None =>
          match MapGet _ (fst cfg) node with
          | None =>
              if Neqb node BDDzero
              then (BDDneg_memo_put cfg BDDzero BDDone, BDDone)
              else (BDDneg_memo_put cfg BDDone BDDzero, BDDzero)
          | Some (x, (l, r)) =>
              match BDDneg_1 cfg ul l bound' with
              | (cfgl, nodel) =>
                  match BDDneg_1 cfgl (nodel :: ul) r bound' with
                  | (cfgr, noder) =>
                      match
                        BDDmake gc cfgr x nodel noder (noder :: nodel :: ul)
                      with
                      | (cfg', node') =>
                          (BDDneg_memo_put cfg' node node', node')
                      end
                  end
              end
          end
      end
  end.

(* Specifications: *)
Lemma BDDneg_1_lemma : forall (bound : nat) (cfg : BDDconfig) (ul : list ad) (node : ad), nat_of_N (node_height cfg node) < bound -> BDDconfig_OK cfg -> used_list_OK cfg ul -> used_node' cfg ul node -> BDDconfig_OK (fst (BDDneg_1 cfg ul node bound)) /\ config_node_OK (fst (BDDneg_1 cfg ul node bound)) (snd (BDDneg_1 cfg ul node bound)) /\ used_nodes_preserved cfg (fst (BDDneg_1 cfg ul node bound)) ul /\ Neqb (node_height (fst (BDDneg_1 cfg ul node bound)) (snd (BDDneg_1 cfg ul node bound))) (node_height cfg node) = true /\ bool_fun_eq (bool_fun_of_BDD (fst (BDDneg_1 cfg ul node bound)) (snd (BDDneg_1 cfg ul node bound))) (bool_fun_neg (bool_fun_of_BDD cfg node)).