Definition BDDneg_memo_OK_1 (cfg : BDDconfig) (memo : BDDneg_memo) :=
  forall (node node' : ad) (bound : nat),
  config_node_OK cfg node ->
  BDDneg_memo_lookup memo node = Some node' ->
  (is_internal_node cfg node -> nat_of_N (var cfg node) < bound) ->
  BDDneg_2 cfg node bound = (cfg, node').Definition BDDneg_memo_OK_2 (cfg : BDDconfig) (memo : BDDneg_memo) :=
  forall (node node' : ad) (bound : nat),
  BDDneg_memo_lookup memo node = Some node' ->
  (is_internal_node cfg node -> nat_of_N (var cfg node) < bound) ->
  config_node_OK cfg node /\ BDDneg_2 cfg node bound = (cfg, node').Fixpoint BDDneg_1 (arg : BDDconfig * ad * BDDneg_memo) 
 (bound : nat) {struct bound} : BDDconfig * ad * BDDneg_memo :=
  match BDDneg_memo_lookup (snd arg) (snd (fst arg)) with
  | Some node => (fst (fst arg), node, snd arg)
  | None =>
      match MapGet _ (fst (fst (fst arg))) (snd (fst arg)) with
      | None =>
          if Neqb (snd (fst arg)) BDDzero
          then
           (fst (fst arg), BDDone, BDDneg_memo_put (snd arg) BDDzero BDDone)
          else
           (fst (fst arg), BDDzero, BDDneg_memo_put (snd arg) BDDone BDDzero)
      | Some (x, (l, r)) =>
          match bound with
          | O => (initBDDconfig, BDDzero, newMap ad)
          | S bound' =>
              (BDDmake
                 (fst
                    (fst
                       (BDDneg_1
                          (fst
                             (fst
                                (BDDneg_1 (fst (fst arg), l, snd arg) bound')),
                          r,
                          snd (BDDneg_1 (fst (fst arg), l, snd arg) bound'))
                          bound'))) x
                 (snd (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')))
                 (snd
                    (fst
                       (BDDneg_1
                          (fst
                             (fst
                                (BDDneg_1 (fst (fst arg), l, snd arg) bound')),
                          r,
                          snd (BDDneg_1 (fst (fst arg), l, snd arg) bound'))
                          bound'))),
              BDDneg_memo_put
                (snd
                   (BDDneg_1
                      (fst
                         (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')),
                      r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound'))
                      bound')) (snd (fst arg))
                (snd
                   (BDDmake
                      (fst
                         (fst
                            (BDDneg_1
                               (fst
                                  (fst
                                     (BDDneg_1 (fst (fst arg), l, snd arg)
                                        bound')), r,
                               snd
                                 (BDDneg_1 (fst (fst arg), l, snd arg) bound'))
                               bound'))) x
                      (snd
                         (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')))
                      (snd
                         (fst
                            (BDDneg_1
                               (fst
                                  (fst
                                     (BDDneg_1 (fst (fst arg), l, snd arg)
                                        bound')), r,
                               snd
                                 (BDDneg_1 (fst (fst arg), l, snd arg) bound'))
                               bound'))))))
          end
      end
  end.

(* Specifications: *)
Lemma BDDneg_1_lemma_1 : forall (arg : BDDconfig * ad * BDDneg_memo) (node : ad) (bound : nat), BDDneg_memo_lookup (snd arg) (snd (fst arg)) = Some node -> BDDneg_1 arg bound = (fst (fst arg), node, snd arg).
Lemma BDDneg_1_lemma_2 : forall (arg : BDDconfig * ad * BDDneg_memo) (bound : nat), BDDneg_memo_lookup (snd arg) (snd (fst arg)) = None -> MapGet _ (fst (fst (fst arg))) (snd (fst arg)) = None -> BDDneg_1 arg bound = (if Neqb (snd (fst arg)) BDDzero then (fst (fst arg), BDDone, BDDneg_memo_put (snd arg) BDDzero BDDone) else (fst (fst arg), BDDzero, BDDneg_memo_put (snd arg) BDDone BDDzero)).
Lemma BDDneg_1_lemma_3 : forall (arg : BDDconfig * ad * BDDneg_memo) (x : BDDvar) (l r : ad), BDDneg_memo_lookup (snd arg) (snd (fst arg)) = None -> MapGet _ (fst (fst (fst arg))) (snd (fst arg)) = Some (x, (l, r)) -> BDDneg_1 arg 0 = (initBDDconfig, BDDzero, newMap ad).
Lemma nat_sum : forall n : nat, {m : nat | n = S m} + {n = 0}.
Lemma BDDneg_1_lemma_4 : forall (arg : BDDconfig * ad * BDDneg_memo) (x : BDDvar) (l r : ad) (bound bound' : nat), bound = S bound' -> BDDneg_memo_lookup (snd arg) (snd (fst arg)) = None -> MapGet _ (fst (fst (fst arg))) (snd (fst arg)) = Some (x, (l, r)) -> BDDneg_1 arg bound = (BDDmake (fst (fst (BDDneg_1 (fst (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')), r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound')) bound'))) x (snd (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound'))) (snd (fst (BDDneg_1 (fst (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')), r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound')) bound'))), BDDneg_memo_put (snd (BDDneg_1 (fst (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')), r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound')) bound')) (snd (fst arg)) (snd (BDDmake (fst (fst (BDDneg_1 (fst (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')), r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound')) bound'))) x (snd (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound'))) (snd (fst (BDDneg_1 (fst (fst (BDDneg_1 (fst (fst arg), l, snd arg) bound')), r, snd (BDDneg_1 (fst (fst arg), l, snd arg) bound')) bound')))))).
Lemma bool_fun_restrict_neg_1 : forall (bf : bool_fun) (x : BDDvar) (b : bool), bool_fun_ext bf -> bool_fun_eq (bool_fun_restrict (bool_fun_neg bf) x b) (bool_fun_neg (bool_fun_restrict bf x b)).
Lemma bool_fun_neg_eq_var_2 : forall (cfg : BDDconfig) (node node' : ad), BDDconfig_OK cfg -> is_internal_node cfg node -> is_internal_node cfg node' -> bool_fun_eq (bool_fun_of_BDD cfg node') (bool_fun_neg (bool_fun_of_BDD cfg node)) -> var cfg node = var cfg node'.
Lemma BDDneg_memo_OK_1_lemma_1_1_1 : forall (bound : nat) (cfg : BDDconfig) (node node' : ad), BDDconfig_OK cfg -> config_node_OK cfg node -> config_node_OK cfg node' -> (is_internal_node cfg node -> nat_of_N (var cfg node) < bound) -> bool_fun_eq (bool_fun_of_BDD cfg node') (bool_fun_neg (bool_fun_of_BDD cfg node)) -> BDDneg_2 cfg node bound = (cfg, node').
Lemma BDDneg_memo_OK_1_2 : forall (cfg : BDDconfig) (memo : BDDneg_memo), BDDneg_memo_OK_2 cfg memo -> BDDneg_memo_OK_1 cfg memo.
Lemma BDDneg_memo_OK_bool_fun_1 : forall (cfg : BDDconfig) (memo : BDDneg_memo) (node node' : ad), BDDconfig_OK cfg -> BDDneg_memo_OK_1 cfg memo -> config_node_OK cfg node -> BDDneg_memo_lookup memo node = Some node' -> bool_fun_eq (bool_fun_of_BDD cfg node') (bool_fun_neg (bool_fun_of_BDD cfg node)).
Lemma BDDneg_memo_OK_bool_fun_1' : forall (cfg : BDDconfig) (memo : BDDneg_memo) (node node' : ad), BDDconfig_OK cfg -> BDDneg_memo_OK_2 cfg memo -> config_node_OK cfg node -> BDDneg_memo_lookup memo node = Some node' -> bool_fun_eq (bool_fun_of_BDD cfg node') (bool_fun_neg (bool_fun_of_BDD cfg node)).