(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)


Require Import Bool.
Require Import Sumbool.
Require Import Arith.
Require Import ZArith NArith Nnat Ndec Ndigits.
From IntMap Require Import Map.
From IntMap Require Import Allmaps.
Require Import List.
Require Import Wf_nat.

Require Import misc.
Require Import bool_fun.
Require Import myMap.
Require Import config.
Require Import alloc.
Require Import make.

Section BDD_neg.

Variable gc : BDDconfig -> list ad -> BDDconfig.
Hypothesis gc_is_OK : gc_OK gc.

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.
  
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)).
Proof.
(* Goal: forall (bound : nat) (cfg : BDDconfig) (ul : list ad) (node : ad) (_ : lt (N.to_nat (node_height cfg node)) bound) (_ : BDDconfig_OK cfg) (_ : used_list_OK cfg ul) (_ : used_node' cfg ul node), and (BDDconfig_OK (@fst BDDconfig ad (BDDneg_1 cfg ul node bound))) (and (config_node_OK (@fst BDDconfig ad (BDDneg_1 cfg ul node bound)) (@snd BDDconfig ad (BDDneg_1 cfg ul node bound))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (BDDneg_1 cfg ul node bound)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (BDDneg_1 cfg ul node bound)) (@snd BDDconfig ad (BDDneg_1 cfg ul node bound))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_1 cfg ul node bound)) (@snd BDDconfig ad (BDDneg_1 cfg ul node bound))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  simple induction bound.  intros.  absurd (nat_of_N (node_height cfg node) < 0).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply lt_n_O.  assumption.  simpl in |- *.  intros.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (and (config_node_OK (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (option_sum _ (MapGet _ (negm_of_cfg cfg) node)).  intro y.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim y; clear y; intros node' H4.  rewrite H4.  simpl in |- *.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (negm_of_cfg_OK _ H1 node node' H4).  intros.  split.  assumption.
(* Goal: BDDconfig_OK cfg *)
  split.  inversion H6.  inversion H8.  assumption.  split.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  apply used_nodes_preserved_refl.  split.  exact (proj1 (proj2 H6)).
(* Goal: forall _ : @eq (option ad) (MapGet ad (negm_of_cfg cfg) node) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (and (config_node_OK (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end) (@snd BDDconfig ad match MapGet ad (negm_of_cfg cfg) node with | Some node' => @pair BDDconfig ad cfg node' | None => match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  exact (proj2 (proj2 H6)).  intro y.  rewrite y.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (option_sum _ (MapGet (BDDvar * (ad * ad)) (fst cfg) node)).  intro y0.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim y0; clear y0.
(* Goal: forall (x : prod BDDvar (prod ad ad)) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@Some (prod BDDvar (prod ad ad)) x)), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x0 (pair l r as p1) as p0) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x0 nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intro x; elim x; clear x; intros x x0; elim x0; clear x0; intros l r H4.
(* Goal: @eq N match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => ad_S x | None => N0 end (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite H4.  elim (prod_sum _ _ (BDDneg_1 cfg ul l n)).  intros cfgl H5.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (config_node_OK (@fst BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim H5; clear H5.  intros nodel H5.  rewrite H5.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (config_node_OK (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (prod_sum _ _ (BDDneg_1 cfgl (nodel :: ul) r n)).  intros cfgr H6.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (config_node_OK (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim H6; clear H6; intros noder H6.  rewrite H6.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (config_node_OK (@fst BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node')) (@snd BDDconfig ad (let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node'))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (prod_sum _ _ (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intros cfg' H7; elim H7; clear H7; intros node' H7.  rewrite H7.  simpl in |- *.
(* Goal: and (BDDconfig_OK (BDDneg_memo_put cfg' node node')) (and (config_node_OK (BDDneg_memo_put cfg' node node') node') (and (used_nodes_preserved cfg (BDDneg_memo_put cfg' node node') ul) (and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg' node node') node') (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg' node node') node') (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (nat_of_N (node_height cfg l) < n).  cut (nat_of_N (node_height cfg r) < n).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intros.  cut (used_node' cfg ul l).  cut (used_node' cfg ul r).  intros.
  cut
   (BDDconfig_OK cfgl /\
    config_node_OK cfgl nodel /\
    used_nodes_preserved cfg cfgl ul /\
    Neqb (node_height cfgl nodel) (node_height cfg l) = true /\
    bool_fun_eq (bool_fun_of_BDD cfgl nodel)
      (bool_fun_neg (bool_fun_of_BDD cfg l))).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intro.  elim H12; clear H12; intros.  elim H13; clear H13; intros.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim H14; clear H14; intros.  elim H15; clear H15; intros.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (config_node_OK cfg l).  cut (config_node_OK cfg r).  intros.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (used_list_OK cfgl ul).  intro.  cut (used_list_OK cfgl (nodel :: ul)).
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  intro.  cut (used_node' cfgl ul r).  intro.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (used_node' cfgl (r :: ul) r).  intro.
  cut
   (BDDconfig_OK cfgr /\
    config_node_OK cfgr noder /\
    used_nodes_preserved cfgl cfgr (nodel :: ul) /\
    Neqb (node_height cfgr noder) (node_height cfgl r) = true /\
    bool_fun_eq (bool_fun_of_BDD cfgr noder)
      (bool_fun_neg (bool_fun_of_BDD cfgl r))).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intros.  elim H23; clear H23; intros.  elim H24; clear H24; intros.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim H25; clear H25; intros.  elim H26; clear H26; intros.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (used_list_OK cfgr (nodel :: ul)).  intro.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (used_list_OK cfgr (noder :: nodel :: ul)).  intro.
(* Goal: and (BDDconfig_OK (BDDneg_memo_put cfg' node node')) (and (config_node_OK (BDDneg_memo_put cfg' node node') node') (and (used_nodes_preserved cfg (BDDneg_memo_put cfg' node node') ul) (and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg' node node') node') (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg' node node') node') (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (used_node' cfgr (noder :: nodel :: ul) nodel).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (used_node' cfgr (noder :: nodel :: ul) noder).  intros.
  cut
   (forall (xl : BDDvar) (ll rl : ad),
    MapGet _ (fst cfgr) nodel = Some (xl, (ll, rl)) ->
    BDDcompare xl x = Datatypes.Lt).
  cut
   (forall (xr : BDDvar) (lr rr : ad),
    MapGet _ (fst cfgr) noder = Some (xr, (lr, rr)) ->
    BDDcompare xr x = Datatypes.Lt).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intros.  cut (BDDconfig_OK cfg').
(* Goal: forall _ : BDDconfig_OK cfg', and (BDDconfig_OK (BDDneg_memo_put cfg' node node')) (and (config_node_OK (BDDneg_memo_put cfg' node node') node') (and (used_nodes_preserved cfg (BDDneg_memo_put cfg' node node') ul) (and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg' node node') node') (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg' node node') node') (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (used_nodes_preserved cfgr cfg' (noder :: nodel :: ul)).
(* Goal: forall (_ : used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul))) (_ : BDDconfig_OK cfg'), and (BDDconfig_OK (BDDneg_memo_put cfg' node node')) (and (config_node_OK (BDDneg_memo_put cfg' node node') node') (and (used_nodes_preserved cfg (BDDneg_memo_put cfg' node node') ul) (and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg' node node') node') (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg' node node') node') (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (config_node_OK cfg' node').
  cut
   (bool_fun_eq (bool_fun_of_BDD cfg' node')
      (bool_fun_if x (bool_fun_of_BDD cfgr noder)
         (bool_fun_of_BDD cfgr nodel))).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  cut (Neqb (node_height cfg' node') (ad_S x) = true).  intros.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (config_node_OK cfg' node).  intro.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (nodes_preserved cfg' (BDDneg_memo_put cfg' node node')).  intro.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (BDDconfig_OK (BDDneg_memo_put cfg' node node')).  intro.  split.
(* Goal: BDDconfig_OK cfg *)
  assumption.  split.  apply nodes_preserved_config_node_OK with (cfg1 := cfg').
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  split.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgr).  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgl).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := nodel).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfg').  assumption.
(* Goal: used_nodes_preserved cfgr cfg' ul *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved_cons with (node := nodel).
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad nodel ul) *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved_cons with (node := noder).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply nodes_preserved_used_nodes_preserved.  assumption.
  rewrite
   (Neqb_complete (node_height (BDDneg_memo_put cfg' node node') node')
      (node_height cfg' node')).
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  split.  rewrite (Neqb_complete _ _ H34).  unfold node_height in |- *.  unfold bs_node_height in |- *.
(* Goal: @eq N match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => ad_S x | None => N0 end (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite H4.  apply Neqb_correct.  
(* Goal: bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg' node node') node') (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
(* Goal: @eq bool (N.eqb (node_height (BDDneg_memo_put cfg' node node') node') (node_height cfg' node')) true *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg' node node') *)
(* Goal: nodes_preserved cfg' (BDDneg_memo_put cfg' node node') *)
(* Goal: config_node_OK cfg' node *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfg' node').
(* Goal: BDDconfig_OK cfg *)
  apply nodes_preserved_bool_fun.  assumption.  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_if x (bool_fun_of_BDD cfgr noder)
                (bool_fun_of_BDD cfgr nodel)).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r))
                (bool_fun_neg (bool_fun_of_BDD cfg l))).
(* Goal: bool_fun_eq (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) (bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r)) (bool_fun_neg (bool_fun_of_BDD cfg l))) *)
(* Goal: bool_fun_eq (bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r)) (bool_fun_neg (bool_fun_of_BDD cfg l))) (bool_fun_neg (bool_fun_of_BDD cfg' node)) *)
(* Goal: nodes_preserved cfg' (BDDneg_memo_put cfg' node node') *)
(* Goal: config_node_OK cfg' node *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_if_preserves_eq.  apply bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfgl r)).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_neg_preserves_eq.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved'_bool_fun with (ul := ul).
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  assumption.  
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg l)) (bool_fun_neg (bool_fun_of_BDD cfgl r)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfgl nodel).
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_bool_fun with (ul := nodel :: ul).  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  apply used_node'_cons_node_ul.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_eq_sym.
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_neg
                (bool_fun_if x (bool_fun_of_BDD cfg r)
                   (bool_fun_of_BDD cfg l))).
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_neg_preserves_eq.  apply bool_fun_of_BDD_int.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_neg_orthogonal.  apply nodes_preserved_node_height_eq.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  apply BDDnegm_put_OK.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  rewrite (Neqb_complete _ _ H34).
(* Goal: @eq comparison (BDDcompare (node_height cfg l) (node_height cfg node)) Lt *)
(* Goal: lt (N.to_nat (node_height cfg node)) (S n) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (Neqb_complete (node_height cfg' node) (node_height cfg node)).  unfold node_height in |- *.
(* Goal: @eq N match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => ad_S x | None => N0 end (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  unfold bs_node_height in |- *.  rewrite H4.  apply Neqb_correct.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_node_height_eq with (ul := ul).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgl).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgr).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := nodel).  assumption.  
(* Goal: used_nodes_preserved cfgr cfg' ul *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved_cons with (node := nodel).
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := noder).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_if x (bool_fun_of_BDD cfgr noder)
                (bool_fun_of_BDD cfgr nodel)).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r))
                (bool_fun_neg (bool_fun_of_BDD cfg l))).
(* Goal: bool_fun_eq (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) (bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r)) (bool_fun_neg (bool_fun_of_BDD cfg l))) *)
(* Goal: bool_fun_eq (bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r)) (bool_fun_neg (bool_fun_of_BDD cfg l))) (bool_fun_neg (bool_fun_of_BDD cfg' node)) *)
(* Goal: nodes_preserved cfg' (BDDneg_memo_put cfg' node node') *)
(* Goal: config_node_OK cfg' node *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_if_preserves_eq.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfg r)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgr nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)) *)
(* Goal: bool_fun_eq (bool_fun_if x (bool_fun_neg (bool_fun_of_BDD cfg r)) (bool_fun_neg (bool_fun_of_BDD cfg l))) (bool_fun_neg (bool_fun_of_BDD cfg' node)) *)
(* Goal: nodes_preserved cfg' (BDDneg_memo_put cfg' node node') *)
(* Goal: config_node_OK cfg' node *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfgl r)).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_neg_preserves_eq.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved'_bool_fun with (ul := ul).
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  assumption.  
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg l)) (bool_fun_neg (bool_fun_of_BDD cfgl r)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfgl nodel).
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_bool_fun with (ul := nodel :: ul).  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  apply used_node'_cons_node_ul.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply
   bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfg node)).
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_neg
                (bool_fun_if x (bool_fun_of_BDD cfg r)
                   (bool_fun_of_BDD cfg l))).
(* Goal: bool_fun_eq bool_fun_one (bool_fun_of_BDD cfg BDDone) *)
  apply bool_fun_eq_sym.  apply bool_fun_neg_orthogonal.
(* Goal: bool_fun_eq (bool_fun_neg bool_fun_one) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_neg_preserves_eq.  apply bool_fun_eq_sym.
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_of_BDD_int.  assumption.  assumption.
(* Goal: bool_fun_eq (bool_fun_neg bool_fun_one) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_neg_preserves_eq.  apply bool_fun_eq_sym.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_bool_fun with (ul := ul).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgl).  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_trans with (cfg2 := cfgr).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := nodel).  assumption.  
(* Goal: used_nodes_preserved cfgr cfg' ul *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved_cons with (node := nodel).
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := noder).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply BDDnegm_put_nodes_preserved.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_node_OK' with (ul := ul) (cfg := cfg).  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  apply used_nodes_preserved_trans with (cfg2 := cfgl).
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  apply used_nodes_preserved_trans with (cfg2 := cfgr).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply used_nodes_preserved_cons with (node := nodel).  assumption.
(* Goal: used_nodes_preserved cfgr cfg' ul *)
(* Goal: @eq bool (N.eqb (node_height cfg' node') (ad_S x)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply used_nodes_preserved_cons with (node := nodel).
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_cons with (node := noder).  assumption.
  replace cfg' with
   (fst (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
  replace node' with
   (snd (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply BDDmake_node_height_eq.  assumption.  intros.  apply not_true_is_false.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  unfold not in |- *; intro.  apply eq_true_false_abs with (b := Neqb l r).
(* Goal: BDDconfig_OK cfg *)
  apply BDDunique with (cfg := cfg).  assumption.  assumption.  assumption.  
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg l) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfgl r).
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg l) (bool_fun_of_BDD cfgl r) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_neg_eq.
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg l)) (bool_fun_neg (bool_fun_of_BDD cfgl r)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfgl nodel).
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_eq_sym.  assumption.  
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfgl r)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfgl r) (bool_fun_of_BDD cfg r) *)
(* Goal: @eq bool (N.eqb l r) false *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)))) cfg' *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg' node') (bool_fun_if x (bool_fun_of_BDD cfgr noder) (bool_fun_of_BDD cfgr nodel)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: used_nodes_preserved cfgr cfg' (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: BDDconfig_OK cfg' *)
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfgr nodel).
(* Goal: bool_fun_eq bool_fun_one (bool_fun_of_BDD cfg BDDone) *)
  apply bool_fun_eq_sym.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_bool_fun with (ul := nodel :: ul).  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  apply used_node'_cons_node_ul.
(* Goal: BDDconfig_OK cfg *)
  rewrite (Neqb_complete _ _ H34).  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_bool_fun with (ul := ul).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply low_high_neq with (cfg := cfg) (node := node) (x := x).  assumption.  assumption.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  rewrite H7.  reflexivity.  rewrite H7.  reflexivity.  
  replace cfg' with
   (fst (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
  replace node' with
   (snd (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: BDDconfig_OK cfg *)
  apply BDDmake_bool_fun.  assumption.  assumption.  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  rewrite H7.  reflexivity.  rewrite H7.
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  reflexivity.  replace cfg' with
   (fst (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
  replace node' with
   (snd (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: BDDconfig_OK cfg *)
  apply BDDmake_node_OK.  assumption.  assumption.  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  rewrite H7.  reflexivity.  rewrite H7.
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  reflexivity.  replace cfg' with
   (fst (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
  replace node' with
   (snd (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: BDDconfig_OK cfg *)
  apply BDDmake_preserves_used_nodes.  assumption.  assumption.  assumption.  
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  rewrite H7.  reflexivity.  rewrite H7.  reflexivity.
  replace cfg' with
   (fst (BDDmake gc cfgr x nodel noder (noder :: nodel :: ul))).
(* Goal: BDDconfig_OK cfg *)
  apply BDDmake_keeps_config_OK.  assumption.  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  rewrite H7.  reflexivity.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  intros.  rewrite (ad_S_compare xr x).
(* Goal: @eq comparison (BDDcompare (ad_S xr) (ad_S x)) Lt *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace (ad_S xr) with (bs_node_height (fst cfgr) noder).
(* Goal: @eq comparison (BDDcompare (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S x)) Lt *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace (ad_S x) with (bs_node_height (fst cfg) node).  unfold node_height in H26.
(* Goal: @eq comparison (BDDcompare (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node)) Lt *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) noder) (ad_S xr) *)
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (Neqb_complete _ _ H26).  cut (Neqb (node_height cfgl r) (node_height cfg r) = true).
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  intro.  unfold node_height in H33.  rewrite (Neqb_complete _ _ H33).
(* Goal: BDDconfig_OK cfg *)
  apply bs_node_height_right with (x := x) (l := l).  exact (proj1 H1).  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_node_height_eq with (ul := ul).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  unfold bs_node_height in |- *.  rewrite H4.
(* Goal: forall (xl : BDDvar) (ll rl : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  reflexivity.  unfold bs_node_height in |- *.  rewrite H32.  reflexivity.  intros.
(* Goal: @eq comparison (BDDcompare xl x) Lt *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (ad_S_compare xl x).  replace (ad_S xl) with (bs_node_height (fst cfgr) nodel).
(* Goal: @eq comparison (BDDcompare (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S x)) Lt *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace (ad_S x) with (bs_node_height (fst cfg) node).
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (Neqb (node_height cfgr nodel) (node_height cfgl nodel) = true).  intro.
(* Goal: @eq comparison (BDDcompare (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node)) Lt *)
(* Goal: @eq bool (N.eqb (node_height cfgr nodel) (node_height cfgl nodel)) true *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  unfold node_height in H33.  rewrite (Neqb_complete _ _ H33).  unfold node_height in H15.
(* Goal: @eq comparison (BDDcompare (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgl) nodel) (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node)) Lt *)
(* Goal: @eq bool (N.eqb (node_height cfgr nodel) (node_height cfgl nodel)) true *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (Neqb_complete _ _ H15).  apply bs_node_height_left with (x := x) (r := r).
(* Goal: BDDconfig_OK cfg *)
  exact (proj1 H1).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_node_height_eq with (ul := nodel :: ul).  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  apply used_node'_cons_node_ul.  
(* Goal: @eq N match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => ad_S x | None => N0 end (ad_S x) *)
(* Goal: @eq N (bs_node_height (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfgr) nodel) (ad_S xl) *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) noder *)
(* Goal: used_node' cfgr (@cons ad noder (@cons ad nodel ul)) nodel *)
(* Goal: used_list_OK cfgr (@cons ad noder (@cons ad nodel ul)) *)
(* Goal: used_list_OK cfgr (@cons ad nodel ul) *)
(* Goal: and (BDDconfig_OK cfgr) (and (config_node_OK cfgr noder) (and (used_nodes_preserved cfgl cfgr (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height cfgr noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD cfgr noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  unfold bs_node_height in |- *.  rewrite H4.  reflexivity.  unfold bs_node_height in |- *.  rewrite H32.
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  reflexivity.  apply used_node'_cons_node_ul.  apply used_node'_cons_node'_ul.
(* Goal: BDDconfig_OK cfg *)
  apply used_node'_cons_node_ul.  apply node_OK_list_OK.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply used_nodes_preserved_list_OK with (cfg := cfgl).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  replace cfgr with (fst (BDDneg_1 cfgl (nodel :: ul) r n)).
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n))) (and (config_node_OK (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) noder) (and (used_nodes_preserved cfgl (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) (@cons ad nodel ul)) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) noder) (node_height cfgl r)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) noder) (bool_fun_neg (bool_fun_of_BDD cfgl r)))))) *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) cfgr *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace noder with (snd (BDDneg_1 cfgl (nodel :: ul) r n)).  apply H.
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply lt_trans_1 with (y := nat_of_N (node_height cfg node)).
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (Neqb (node_height cfgl r) (node_height cfg r) = true).  intro.
(* Goal: @eq comparison (BDDcompare (node_height cfg l) (node_height cfg node)) Lt *)
(* Goal: lt (N.to_nat (node_height cfg node)) (S n) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (Neqb_complete _ _ H23).  apply BDDcompare_lt.  unfold node_height in |- *.
(* Goal: BDDconfig_OK cfg *)
  apply bs_node_height_right with (x := x) (l := l).  exact (proj1 H1).  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved'_node_height_eq with (ul := ul).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  apply used_node'_cons_node'_ul.  assumption.  rewrite H6.  reflexivity.  
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDneg_1 cfgl (@cons ad nodel ul) r n)) cfgr *)
(* Goal: used_node' cfgl (@cons ad r ul) r *)
(* Goal: used_node' cfgl ul r *)
(* Goal: used_list_OK cfgl (@cons ad nodel ul) *)
(* Goal: used_list_OK cfgl ul *)
(* Goal: config_node_OK cfg r *)
(* Goal: config_node_OK cfg l *)
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite H6.  reflexivity.  apply used_node'_cons_node_ul.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_used_node' with (cfg := cfg).  assumption.  assumption.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply node_OK_list_OK.  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_nodes_preserved_list_OK with (cfg := cfg).  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_node'_OK with (ul := ul).  assumption.  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  apply used_node'_OK with (ul := ul).  assumption.  assumption.  assumption.  
(* Goal: and (BDDconfig_OK cfgl) (and (config_node_OK cfgl nodel) (and (used_nodes_preserved cfg cfgl ul) (and (@eq bool (N.eqb (node_height cfgl nodel) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD cfgl nodel) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace cfgl with (fst (BDDneg_1 cfg ul l n)).
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (BDDneg_1 cfg ul l n))) (and (config_node_OK (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) (@snd BDDconfig ad (BDDneg_1 cfg ul l n))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) (@snd BDDconfig ad (BDDneg_1 cfg ul l n))) (node_height cfg l)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) (@snd BDDconfig ad (BDDneg_1 cfg ul l n))) (bool_fun_neg (bool_fun_of_BDD cfg l)))))) *)
(* Goal: @eq ad (@snd BDDconfig ad (BDDneg_1 cfg ul l n)) nodel *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) cfgl *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  replace nodel with (snd (BDDneg_1 cfg ul l n)).  apply H.
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply lt_trans_1 with (y := nat_of_N (node_height cfg node)).  apply BDDcompare_lt.
(* Goal: @eq comparison (BDDcompare (node_height cfg l) (node_height cfg node)) Lt *)
(* Goal: lt (N.to_nat (node_height cfg node)) (S n) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  unfold node_height in |- *.  apply bs_node_height_left with (x := x) (r := r).  exact (proj1 H1).
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  assumption.  assumption.  assumption.  rewrite H5.
(* Goal: @eq BDDconfig (@fst BDDconfig ad (BDDneg_1 cfg ul l n)) cfgl *)
(* Goal: used_node' cfg ul r *)
(* Goal: used_node' cfg ul l *)
(* Goal: lt (N.to_nat (node_height cfg r)) n *)
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  reflexivity.  rewrite H5.  reflexivity.  
(* Goal: BDDconfig_OK cfg *)
  apply high_used' with (x := x) (l := l) (node := node).  assumption.  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply low_used' with (x := x) (r := r) (node := node).  assumption.  
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  apply lt_trans_1 with (y := nat_of_N (node_height cfg node)).
(* Goal: @eq comparison (BDDcompare (node_height cfg l) (node_height cfg node)) Lt *)
(* Goal: lt (N.to_nat (node_height cfg node)) (S n) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply BDDcompare_lt.  unfold node_height in |- *.  apply bs_node_height_right with (x := x) (l := l).
(* Goal: BDDconfig_OK cfg *)
  exact (proj1 H1).  assumption.  assumption.
(* Goal: lt (N.to_nat (node_height cfg l)) n *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply lt_trans_1 with (y := nat_of_N (node_height cfg node)).  apply BDDcompare_lt.
(* Goal: @eq comparison (BDDcompare (node_height cfg l) (node_height cfg node)) Lt *)
(* Goal: lt (N.to_nat (node_height cfg node)) (S n) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node) (@None (prod BDDvar (prod ad ad))), and (BDDconfig_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (config_node_OK (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (and (used_nodes_preserved cfg (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end) (@snd BDDconfig ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg) node with | Some (pair x (pair l r as p0) as p) => let (cfgl, nodel) := BDDneg_1 cfg ul l n in let (cfgr, noder) := BDDneg_1 cfgl (@cons ad nodel ul) r n in let (cfg', node') := BDDmake gc cfgr x nodel noder (@cons ad noder (@cons ad nodel ul)) in @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) ad (BDDneg_memo_put cfg' node node') node' | None => if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero end)) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  unfold node_height in |- *.  apply bs_node_height_left with (x := x) (r := r).  exact (proj1 H1).
(* Goal: BDDconfig_OK cfg *)
  assumption.  assumption.  intro y0.  rewrite y0.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  elim (sumbool_of_bool (Neqb node BDDzero)).  intro y1.  rewrite y1.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite (Neqb_complete _ _ y1).  simpl in |- *.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (BDDconfig_OK (BDDneg_memo_put cfg BDDzero BDDone)).  intro.  split.
(* Goal: BDDconfig_OK cfg *)
  assumption.  cut (nodes_preserved cfg (BDDneg_memo_put cfg BDDzero BDDone)).
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  intro.  split.  apply nodes_preserved_config_node_OK with (cfg1 := cfg).
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply one_OK.  split.  apply nodes_preserved_used_nodes_preserved.
(* Goal: BDDconfig_OK cfg *)
  assumption.  split.  rewrite <-
   (Neqb_complete (node_height cfg BDDone) (node_height cfg BDDzero))
   .
(* Goal: BDDconfig_OK cfg *)
  apply nodes_preserved_node_height_eq.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg BDDone *)
(* Goal: config_node_OK cfg BDDzero *)
(* Goal: @eq bool (N.eqb (node_height cfg BDDzero) (node_height cfg BDDone)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply one_OK.  rewrite (Neqb_complete _ _ (node_height_zero _ H1)).
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_one _ H1)).  reflexivity.
(* Goal: bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDzero BDDone) BDDone) (bool_fun_neg (bool_fun_of_BDD cfg BDDzero)) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDzero BDDone) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDzero BDDone) *)
(* Goal: forall _ : @eq bool (N.eqb node BDDzero) false, and (BDDconfig_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_one).  apply bool_fun_of_BDD_one.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_eq_trans with (bf2 := bool_fun_neg bool_fun_zero).
(* Goal: bool_fun_eq bool_fun_one (bool_fun_of_BDD cfg BDDone) *)
  apply bool_fun_eq_sym.  exact bool_fun_neg_zero.
(* Goal: bool_fun_eq (bool_fun_neg bool_fun_one) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_neg_preserves_eq.  apply bool_fun_eq_sym.
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_of_BDD_zero.  assumption.  apply BDDnegm_put_nodes_preserved.
(* Goal: BDDconfig_OK cfg *)
  apply BDDnegm_put_OK.  assumption.  apply zero_OK.  apply one_OK.  
(* Goal: @eq bool (N.eqb (node_height cfg BDDzero) (node_height cfg BDDone)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_zero _ H1)).
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_one _ H1)).  reflexivity.  
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_neg (bool_fun_of_BDD cfg BDDzero)) *)
(* Goal: forall _ : @eq bool (N.eqb node BDDzero) false, and (BDDconfig_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (if N.eqb node BDDzero then @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDzero BDDone) BDDone else @pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_neg bool_fun_zero).  
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_of_BDD_one.  assumption.  apply bool_fun_neg_preserves_eq.
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_eq_sym.  apply bool_fun_of_BDD_zero.  assumption.  intro y1.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (config_node_OK (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (and (used_nodes_preserved cfg (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) ul) (and (@eq bool (N.eqb (node_height (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero)) (@snd BDDconfig ad (@pair (prod BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod (Map ad) (prod BDDor_memo BDDuniv_memo)))))) N (BDDneg_memo_put cfg BDDone BDDzero) BDDzero))) (bool_fun_neg (bool_fun_of_BDD cfg node)))))) *)
  rewrite y1.  simpl in |- *.  cut (BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero)).
(* Goal: BDDconfig_OK cfg *)
  intro.  split.  assumption.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  cut (nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero)).  intro.
(* Goal: BDDconfig_OK cfg *)
  split.  apply nodes_preserved_config_node_OK with (cfg1 := cfg).  assumption.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  apply zero_OK.  split.  apply nodes_preserved_used_nodes_preserved.
(* Goal: BDDconfig_OK cfg *)
  assumption.  elim (used_node'_OK cfg ul node H1 H2 H3).  intro.
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  rewrite H6 in y1.  simpl in y1.  discriminate.  intro.  elim H6.  intro.
(* Goal: and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg BDDone)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone))) *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map (prod BDDfree_list (prod ad (prod BDDneg_memo (prod BDDor_memo BDDuniv_memo))))) cfg)) true, and (@eq bool (N.eqb (node_height (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (node_height cfg node)) true) (bool_fun_eq (bool_fun_of_BDD (BDDneg_memo_put cfg BDDone BDDzero) BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg node))) *)
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  rewrite H7.  split.  rewrite <-
   (Neqb_complete (node_height cfg BDDzero) (node_height cfg BDDone))
   .
(* Goal: BDDconfig_OK cfg *)
  apply nodes_preserved_node_height_eq.  assumption.  assumption.  assumption.
(* Goal: @eq bool (N.eqb (node_height cfg BDDzero) (node_height cfg BDDone)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply zero_OK.  rewrite (Neqb_complete _ _ (node_height_zero _ H1)).
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_one _ H1)).  reflexivity.  
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg bool_fun_one) *)
(* Goal: bool_fun_eq (bool_fun_neg bool_fun_one) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_zero).  apply bool_fun_of_BDD_zero.
(* Goal: BDDconfig_OK cfg *)
  assumption.  apply bool_fun_eq_trans with (bf2 := bool_fun_neg bool_fun_one).
(* Goal: bool_fun_eq bool_fun_one (bool_fun_of_BDD cfg BDDone) *)
  apply bool_fun_eq_sym.  exact bool_fun_neg_one.
(* Goal: bool_fun_eq (bool_fun_neg bool_fun_one) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_neg_preserves_eq.  apply bool_fun_eq_sym.
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_of_BDD_one.  assumption.  intro.  unfold in_dom in H7.
(* Goal: nodes_preserved cfg (BDDneg_memo_put cfg BDDone BDDzero) *)
(* Goal: BDDconfig_OK (BDDneg_memo_put cfg BDDone BDDzero) *)
  rewrite y0 in H7.  discriminate.  apply BDDnegm_put_nodes_preserved.
(* Goal: BDDconfig_OK cfg *)
  apply BDDnegm_put_OK.  assumption.  apply one_OK.  apply zero_OK.  
(* Goal: @eq bool (N.eqb (node_height cfg BDDzero) (node_height cfg BDDone)) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_zero _ H1)).
(* Goal: @eq bool (N.eqb N0 N0) true *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  rewrite (Neqb_complete _ _ (node_height_one _ H1)).  reflexivity.  
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_neg (bool_fun_of_BDD cfg BDDone)) *)
  apply bool_fun_eq_trans with (bf2 := bool_fun_neg bool_fun_one).
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_of_BDD_zero.  assumption.  apply bool_fun_neg_preserves_eq.
(* Goal: BDDconfig_OK cfg *)
  apply bool_fun_eq_sym.  apply bool_fun_of_BDD_one.  assumption.  
Qed.

End BDD_neg.