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.

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).