(* 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 Allmaps.
Require Import Wf_nat.

Require Import BDDvar_ad_nat.
Require Import bdd1.
Require Import bdd2.
Require Import bdd3.
Require Import bdd4.
Require Import bdd5_1.
Require Import bdd5_2.
Require Import bdd6.
Require Import bdd7.
Require Import BDDdummy_lemma_2.
Require Import BDDdummy_lemma_3.
Require Import BDDdummy_lemma_4.
Require Import bdd8.
Require Import bdd9.

Definition BDDneg (cfg : BDDconfig) (memo : BDDneg_memo) 
  (node : ad) :=
  match BDDneg_1_1 cfg memo node (S (nat_of_N (var cfg node))) with
  | ((cfg', node'), memo') => (cfg', (node', memo'))
  end.

Definition BDDor (cfg : BDDconfig) (memo : BDDor_memo) 
  (node1 node2 : ad) :=
  BDDor_1_1 cfg memo node1 node2
    (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).

Definition BDDand (cfg : BDDconfig) (negm : BDDneg_memo) 
  (orm : BDDor_memo) (node1 node2 : ad) :=
  match BDDneg cfg negm node1 with
  | (cfg', (node1', negm')) =>
      match BDDneg cfg' negm' node2 with
      | (cfg'', (node2', negm'')) =>
          match BDDor cfg'' orm node1' node2' with
          | (cfg''', (node, orm')) =>
              match BDDneg cfg''' negm'' node with
              | (cfg'''', (node', negm''')) =>
                  (cfg'''', (node', (negm''', orm')))
              end
          end
      end
  end.

Lemma nodes_preserved_orm_OK :
 forall (cfg cfg' : BDDconfig) (orm : BDDor_memo),
 BDDconfig_OK cfg ->
 BDDconfig_OK cfg' ->
 nodes_preserved cfg cfg' -> BDDor_memo_OK cfg orm -> BDDor_memo_OK cfg' orm.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor_memo_OK in |- *.  intros.  unfold BDDor_memo_OK in H2.  cut (config_node_OK cfg node1).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (config_node_OK cfg node2).  cut (config_node_OK cfg node).  intros.
  cut
   (BDDvar_le (var cfg node) (BDDvar_max (var cfg node1) (var cfg node2)) =
    true).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  cut
   (bool_fun_eq (bool_fun_of_BDD cfg node)
      (bool_fun_or (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  split.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  assumption.
(* Goal: and (config_node_OK cfg' node) (@eq (prod BDDconfig ad) (BDDneg_2 cfg' node bound) (@pair BDDconfig ad cfg' node')) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: config_node_OK cfg' node *)
(* Goal: config_node_OK cfg node' *)
(* Goal: @eq (prod BDDconfig ad) (BDDneg_2 cfg node bound) (@pair BDDconfig ad cfg node') *)
(* Goal: config_node_OK cfg node *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  split.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  assumption.  split.
(* Goal: and (config_node_OK cfg' node) (@eq (prod BDDconfig ad) (BDDneg_2 cfg' node bound) (@pair BDDconfig ad cfg' node')) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: config_node_OK cfg' node *)
(* Goal: config_node_OK cfg node' *)
(* Goal: @eq (prod BDDconfig ad) (BDDneg_2 cfg node bound) (@pair BDDconfig ad cfg node') *)
(* Goal: config_node_OK cfg node *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  apply nodes_preserved_2 with (cfg := cfg).  assumption.  assumption.  split.
(* Goal: lt (N.to_nat (var cfg node)) bound *)
  cut (var cfg' node = var cfg node).  cut (var cfg' node1 = var cfg node1).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (var cfg' node2 = var cfg node2).  intros.  rewrite H9.  rewrite H10.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  rewrite H11.  assumption.  apply nodes_preserved_var_1.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  apply nodes_preserved_var_1.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  apply nodes_preserved_var_1.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfg node).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply nodes_preserved_3.  assumption.  assumption.  assumption.  assumption.
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_or (bool_fun_of_BDD cfg node1)
                (bool_fun_of_BDD cfg node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  apply bool_fun_eq_symm.  apply bool_fun_or_preserves_eq.  apply nodes_preserved_3.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  apply nodes_preserved_3.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  exact (proj2 (proj2 (proj2 (proj2 (H2 node1 node2 node H3))))).
(* Goal: @eq bool (BDDvar_le (var cfg node) (BDDvar_max (var cfg node1) (var cfg node2))) true *)
(* Goal: config_node_OK cfg node *)
(* Goal: config_node_OK cfg node2 *)
(* Goal: config_node_OK cfg node1 *)
  exact (proj1 (proj2 (proj2 (proj2 (H2 node1 node2 node H3))))).  
(* Goal: config_node_OK cfg node *)
(* Goal: config_node_OK cfg node2 *)
(* Goal: config_node_OK cfg node1 *)
  exact (proj1 (proj2 (proj2 (H2 node1 node2 node H3)))).  
(* Goal: config_node_OK cfg node2 *)
(* Goal: config_node_OK cfg node1 *)
  exact (proj1 (proj2 (H2 node1 node2 node H3))).
(* Goal: config_node_OK cfg node1 *)
  exact (proj1 (H2 node1 node2 node H3)).
Qed.

Lemma nodes_preserved_negm_OK :
 forall (cfg cfg' : BDDconfig) (negm : BDDneg_memo),
 BDDconfig_OK cfg ->
 BDDconfig_OK cfg' ->
 nodes_preserved cfg cfg' ->
 BDDneg_memo_OK_2 cfg negm -> BDDneg_memo_OK_2 cfg' negm.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg_memo_OK_2 in |- *.  unfold BDDneg_memo_OK_2 in H2.  intros.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  cut (is_internal_node cfg node -> nat_of_N (var cfg node) < bound).  intro.
(* Goal: and (config_node_OK cfg' node) (@eq (prod BDDconfig ad) (BDDneg_2 cfg' node bound) (@pair BDDconfig ad cfg' node')) *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  cut (config_node_OK cfg node).  cut (BDDneg_2 cfg node bound = (cfg, node')).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  cut (config_node_OK cfg node').  intro.  cut (config_node_OK cfg' node).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (config_node_OK cfg' node').  intros.  split.  assumption.  apply BDDneg_memo_OK_1_lemma_1_1_1.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfg node').
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply nodes_preserved_3.  assumption.  assumption.  assumption.  assumption.  
  apply
   bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfg node)).
  replace (bool_fun_of_BDD cfg node') with
   (bool_fun_of_BDD (fst (BDDneg_2 cfg node bound))
      (snd (BDDneg_2 cfg node bound))).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_2 cfg node bound)) (@snd BDDconfig ad (BDDneg_2 cfg node bound))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_2 cfg node bound)) (@snd BDDconfig ad (BDDneg_2 cfg node bound))) (bool_fun_of_BDD cfg node') *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg node)) (bool_fun_neg (bool_fun_of_BDD cfg' node)) *)
(* Goal: config_node_OK cfg' node' *)
(* Goal: config_node_OK cfg' node *)
(* Goal: config_node_OK cfg node' *)
(* Goal: @eq (prod BDDconfig ad) (BDDneg_2 cfg node bound) (@pair BDDconfig ad cfg node') *)
(* Goal: config_node_OK cfg node *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  refine (proj2 (proj2 (proj2 (proj2 (BDDneg_2_lemma _ _ _ _ _ _))))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H6.  reflexivity.  apply bool_fun_eq_symm.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply bool_fun_eq_neg_1.  apply nodes_preserved_3.  assumption.  assumption.  
(* Goal: config_node_OK (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (BDDand cfg negm orm node1 node2)) node *)
  assumption.  assumption.  apply nodes_preserved_2 with (cfg := cfg).  assumption. 
(* Goal: config_node_OK (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (BDDand cfg negm orm node1 node2)) node *)
  assumption.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  assumption.
(* Goal: config_node_OK cfg node' *)
(* Goal: @eq (prod BDDconfig ad) (BDDneg_2 cfg node bound) (@pair BDDconfig ad cfg node') *)
(* Goal: config_node_OK cfg node *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  replace cfg with (fst (BDDneg_2 cfg node bound)).  replace node' with (snd (BDDneg_2 cfg node bound)).  refine (proj1 (proj2 (proj2 (proj2 (BDDneg_2_lemma _ _ _ _ _ _))))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H6; reflexivity.  rewrite H6; reflexivity.
(* Goal: @eq (prod BDDconfig ad) (BDDneg_2 cfg node bound) (@pair BDDconfig ad cfg node') *)
(* Goal: config_node_OK cfg node *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) bound *)
  exact (proj2 (H2 node node' bound H3 H5)).  exact (proj1 (H2 node node' bound H3 H5)).  
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  cut (var cfg' node = var cfg node).  intro.  rewrite <- H6.  apply H4.
(* Goal: is_internal_node cfg' node *)
(* Goal: @eq BDDvar (var cfg' node) (var cfg node) *)
  inversion H5.  inversion H7.  inversion H8.  split with x.  split with x0.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  split with x1.  apply H1.  assumption.  apply nodes_preserved_var.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.
Qed.

Lemma BDDneg_keeps_config_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node -> BDDconfig_OK (fst (BDDneg cfg negm node)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg in |- *.  elim
   (prod_sum _ _ (BDDneg_1_1 cfg negm node (S (nat_of_N (var cfg node))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros cfg' node'.  intro.  elim H2; clear H2.
(* Goal: forall (x : BDDneg_memo) (_ : @eq (prod (prod BDDconfig ad) BDDneg_memo) (BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node)))) (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg' node') x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
  intros negm' H2.  rewrite H2.  simpl in |- *.  rewrite (BDDneg_1_1_eq_1 (S (nat_of_N (var cfg node))) cfg negm node)
    in H2.
  cut
   (is_internal_node cfg node ->
    nat_of_N (var cfg node) < S (nat_of_N (var cfg node))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  replace cfg' with
   (fst (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  rewrite
   (proj1
      (BDDneg_1_lemma' (S (nat_of_N (var cfg node))) 
         (cfg, node, negm) H H1 H0 H3)).
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  exact (proj1 (BDDneg_2_lemma _ _ _ H H1 H3)).  rewrite H2.  reflexivity.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDneg_node_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 config_node_OK (fst (BDDneg cfg negm node))
   (fst (snd (BDDneg cfg negm node))).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg in |- *.  elim
   (prod_sum _ _ (BDDneg_1_1 cfg negm node (S (nat_of_N (var cfg node))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros cfg' node'.  intro.  elim H2; clear H2.
(* Goal: forall (x : BDDneg_memo) (_ : @eq (prod (prod BDDconfig ad) BDDneg_memo) (BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node)))) (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg' node') x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
  intros negm' H2.  rewrite H2.  simpl in |- *.  rewrite (BDDneg_1_1_eq_1 (S (nat_of_N (var cfg node))) cfg negm node)
    in H2.
  cut
   (is_internal_node cfg node ->
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
    nat_of_N (var cfg node) < S (nat_of_N (var cfg node))).  intro.  replace cfg' with
   (fst (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  replace node' with
   (snd (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  rewrite
   (proj1
      (BDDneg_1_lemma' (S (nat_of_N (var cfg node))) 
         (cfg, node, negm) H H1 H0 H3)).
  exact
   (proj1
      (proj2
         (proj2
            (proj2
               (BDDneg_2_lemma (S (nat_of_N (var cfg node))) cfg node H H1
                  H3))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H2; reflexivity.  rewrite H2; reflexivity.  intro.  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDneg_preserves_nodes :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node -> nodes_preserved cfg (fst (BDDneg cfg negm node)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg in |- *.  elim
   (prod_sum _ _ (BDDneg_1_1 cfg negm node (S (nat_of_N (var cfg node))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros cfg' node'.  intro.  elim H2; clear H2.
(* Goal: forall (x : BDDneg_memo) (_ : @eq (prod (prod BDDconfig ad) BDDneg_memo) (BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node)))) (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg' node') x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
  intros negm' H2.  rewrite H2.  simpl in |- *.  rewrite (BDDneg_1_1_eq_1 (S (nat_of_N (var cfg node))) cfg negm node)
    in H2.
  cut
   (is_internal_node cfg node ->
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
    nat_of_N (var cfg node) < S (nat_of_N (var cfg node))).  intro.  replace cfg' with
   (fst (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
(* Goal: nodes_preserved cfg (@fst BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (BDDneg_1 (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm) (S (N.to_nat (var cfg node)))))) *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (BDDneg_1 (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm) (S (N.to_nat (var cfg node)))))) cfg' *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) (S (N.to_nat (var cfg node))) *)
  unfold nodes_preserved in |- *.  rewrite
   (proj1
      (BDDneg_1_lemma' (S (nat_of_N (var cfg node))) 
         (cfg, node, negm) H H1 H0 H3)).
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  exact (proj1 (proj2 (BDDneg_2_lemma _ _ _ H H1 H3))).  rewrite H2; reflexivity.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDneg_keeps_neg_memo_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 BDDneg_memo_OK_2 (fst (BDDneg cfg negm node))
   (snd (snd (BDDneg cfg negm node))).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg in |- *.  elim
   (prod_sum _ _ (BDDneg_1_1 cfg negm node (S (nat_of_N (var cfg node))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros cfg' node'.  intro.  elim H2; clear H2.
(* Goal: forall (x : BDDneg_memo) (_ : @eq (prod (prod BDDconfig ad) BDDneg_memo) (BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node)))) (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg' node') x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
  intros negm' H2.  rewrite H2.  simpl in |- *.  rewrite (BDDneg_1_1_eq_1 (S (nat_of_N (var cfg node))) cfg negm node)
    in H2.
  cut
   (is_internal_node cfg node ->
    nat_of_N (var cfg node) < S (nat_of_N (var cfg node))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  replace cfg' with
   (fst (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  replace negm' with
   (snd (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node))))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  refine (proj2 (BDDneg_1_lemma' _ _ _ _ _ _)).  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  rewrite H2; reflexivity.  rewrite H2; reflexivity.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  unfold lt in |- *.  apply le_n.
Qed.  
Lemma BDDneg_keeps_or_memo_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 BDDor_memo_OK cfg orm -> BDDor_memo_OK (fst (BDDneg cfg negm node)) orm.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_orm_OK with (cfg := cfg).  assumption.  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  apply BDDneg_preserves_nodes.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.
Qed.

Lemma BDDneg_keeps_node_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 forall node' : ad,
 config_node_OK cfg node' ->
 config_node_OK (fst (BDDneg cfg negm node)) node'.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  apply BDDneg_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.
Qed.

Lemma BDDneg_preserves_bool_fun :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 forall node' : ad,
 config_node_OK cfg node' ->
 bool_fun_eq (bool_fun_of_BDD (fst (BDDneg cfg negm node)) node')
   (bool_fun_of_BDD cfg node').
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_3.  assumption.  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  apply BDDneg_preserves_nodes.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.
Qed.

Lemma BDDneg_is_neg :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (node : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 config_node_OK cfg node ->
 bool_fun_eq
   (bool_fun_of_BDD (fst (BDDneg cfg negm node))
      (fst (snd (BDDneg cfg negm node))))
   (bool_fun_neg (bool_fun_of_BDD cfg node)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDneg in |- *.  elim
   (prod_sum _ _ (BDDneg_1_1 cfg negm node (S (nat_of_N (var cfg node))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros cfg' node'.  intro.  elim H2; clear H2.
(* Goal: forall (x : BDDneg_memo) (_ : @eq (prod (prod BDDconfig ad) BDDneg_memo) (BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node)))) (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg' node') x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (let (p, memo') := BDDneg_1_1 cfg negm node (S (N.to_nat (var cfg node))) in let (cfg', node') := p in @pair BDDconfig (prod ad BDDneg_memo) cfg' (@pair ad BDDneg_memo node' memo'))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
  intros negm' H2.  rewrite H2.  simpl in |- *.  rewrite (BDDneg_1_1_eq_1 (S (nat_of_N (var cfg node))) cfg negm node)
    in H2.
  cut
   (is_internal_node cfg node ->
    nat_of_N (var cfg node) < S (nat_of_N (var cfg node))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  replace cfg' with
   (fst (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  replace node' with
   (snd (fst (BDDneg_1 (cfg, node, negm) (S (nat_of_N (var cfg node)))))).
  rewrite
   (proj1
      (BDDneg_1_lemma' (S (nat_of_N (var cfg node))) 
         (cfg, node, negm) H H1 H0 H3)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig ad (BDDneg_2 (@fst BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm))) (@snd BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm))) (S (N.to_nat (var cfg node))))) (@snd BDDconfig ad (BDDneg_2 (@fst BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm))) (@snd BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm))) (S (N.to_nat (var cfg node)))))) (bool_fun_neg (bool_fun_of_BDD cfg node)) *)
(* Goal: @eq ad (@snd BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (BDDneg_1 (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm) (S (N.to_nat (var cfg node)))))) node' *)
(* Goal: @eq BDDconfig (@fst BDDconfig ad (@fst (prod BDDconfig ad) BDDneg_memo (BDDneg_1 (@pair (prod BDDconfig ad) BDDneg_memo (@pair BDDconfig ad cfg node) negm) (S (N.to_nat (var cfg node)))))) cfg' *)
(* Goal: forall _ : is_internal_node cfg node, lt (N.to_nat (var cfg node)) (S (N.to_nat (var cfg node))) *)
  exact (proj2 (proj2 (proj2 (proj2 (BDDneg_2_lemma _ _ _ H H1 H3))))).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H2; reflexivity.  rewrite H2; reflexivity.  intro.  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDor_keeps_config_OK :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 -> BDDconfig_OK (fst (BDDor cfg orm node1 node2)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor in |- *.  rewrite
   (BDDor_1_1_eq_1
      (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))) cfg
      orm node1 node2).
  cut
   (is_internal_node cfg node1 ->
    is_internal_node cfg node2 ->
    max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) <
    S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  refine (proj1 (BDDor_1_lemma _ _ _ _ _ _ _ _ _ _)).  assumption.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  assumption.  assumption.  assumption.  assumption.  intros.  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDor_node_OK :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 config_node_OK (fst (BDDor cfg orm node1 node2))
   (fst (snd (BDDor cfg orm node1 node2))).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor in |- *.  rewrite
   (BDDor_1_1_eq_1
      (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))) cfg
      orm node1 node2).
  cut
   (is_internal_node cfg node1 ->
    is_internal_node cfg node2 ->
    max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) <
    S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  refine (proj1 (proj2 (proj2 (BDDor_1_lemma _ _ _ _ _ _ _ _ _ _)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  intros.
(* Goal: lt (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2))) (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) *)
  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDor_keeps_or_memo_OK :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 BDDor_memo_OK (fst (BDDor cfg orm node1 node2))
   (snd (snd (BDDor cfg orm node1 node2))).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor in |- *.  rewrite
   (BDDor_1_1_eq_1
      (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))) cfg
      orm node1 node2).
  cut
   (is_internal_node cfg node1 ->
    is_internal_node cfg node2 ->
    max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) <
    S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  refine (proj1 (proj2 (BDDor_1_lemma _ _ _ _ _ _ _ _ _ _))).  
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  intros.
(* Goal: lt (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2))) (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) *)
  unfold lt in |- *.  apply le_n.
Qed.

Lemma BDDor_preserves_nodes :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 nodes_preserved cfg (fst (BDDor cfg orm node1 node2)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor in |- *.  rewrite
   (BDDor_1_1_eq_1
      (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))) cfg
      orm node1 node2).
  cut
   (is_internal_node cfg node1 ->
    is_internal_node cfg node2 ->
    max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) <
    S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  refine (proj1 (proj2 (proj2 (proj2 (BDDor_1_lemma _ _ _ _ _ _ _ _ _ _))))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  intros.  unfold lt in |- *.
(* Goal: le (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) *)
  apply le_n.
Qed.

Lemma BDDor_keeps_node_OK :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 forall node : ad,
 config_node_OK cfg node ->
 config_node_OK (fst (BDDor cfg orm node1 node2)) node.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  apply BDDor_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.
Qed.

Lemma BDDor_preserves_bool_fun :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 forall node : ad,
 config_node_OK cfg node ->
 bool_fun_eq (bool_fun_of_BDD (fst (BDDor cfg orm node1 node2)) node)
   (bool_fun_of_BDD cfg node).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_3.  assumption.  apply BDDor_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  apply BDDor_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.
Qed.

Lemma BDDor_keeps_neg_memo_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDneg_memo_OK_2 (fst (BDDor cfg orm node1 node2)) negm.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_negm_OK with (cfg := cfg).  assumption.  apply BDDor_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  apply BDDor_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.
Qed.

Lemma BDDor_is_or :
 forall (cfg : BDDconfig) (orm : BDDor_memo) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 bool_fun_eq
   (bool_fun_of_BDD (fst (BDDor cfg orm node1 node2))
      (fst (snd (BDDor cfg orm node1 node2))))
   (bool_fun_or (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDor in |- *.  rewrite
   (BDDor_1_1_eq_1
      (S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))) cfg
      orm node1 node2).
  cut
   (is_internal_node cfg node1 ->
    is_internal_node cfg node2 ->
    max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) <
    S (max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  refine
   (proj2 (proj2 (proj2 (proj2 (proj2 (BDDor_1_lemma _ _ _ _ _ _ _ _ _ _)))))).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  intros.  unfold lt in |- *.
(* Goal: le (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) (S (max (N.to_nat (var cfg node1)) (N.to_nat (var cfg node2)))) *)
  apply le_n.
Qed.

Lemma BDDand_keeps_config_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 BDDconfig_OK (fst (BDDand cfg negm orm node1 node2)).
Proof.

(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.


(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.




(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.


Qed.

Lemma BDDand_node_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 config_node_OK (fst (BDDand cfg negm orm node1 node2))
   (fst (snd (BDDand cfg negm orm node1 node2))).
Proof.


(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.


(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace node' with (fst (snd (BDDneg cfg''' negm'' node))).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.



(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.

Qed.

Lemma BDDand_preserves_nodes :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 nodes_preserved cfg (fst (BDDand cfg negm orm node1 node2)).
Proof.

(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.


(* Goal: nodes_preserved cfg cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply nodes_preserved_trans with (cfg2 := cfg').
(* Goal: BDDconfig_OK cfg' *)
replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: nodes_preserved cfg''' (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H4; reflexivity.

(* Goal: nodes_preserved cfg' cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply nodes_preserved_trans with (cfg2 := cfg'').
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: nodes_preserved cfg''' (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H5; reflexivity.

(* Goal: nodes_preserved cfg'' cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply nodes_preserved_trans with (cfg2 := cfg''').
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: nodes_preserved cfg'' (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: nodes_preserved cfg''' cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDor_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H6; reflexivity.

(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: nodes_preserved cfg''' (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.


(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.

Qed.

Lemma BDDand_keeps_node_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 forall node : ad,
 config_node_OK cfg node ->
 config_node_OK (fst (BDDand cfg negm orm node1 node2)) node.
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_2 with (cfg := cfg).  assumption.  apply BDDand_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.
Qed.

Lemma BDDand_preserves_bool_fun :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 forall node : ad,
 config_node_OK cfg node ->
 bool_fun_eq (bool_fun_of_BDD (fst (BDDand cfg negm orm node1 node2)) node)
   (bool_fun_of_BDD cfg node).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  apply nodes_preserved_3.  assumption.  apply BDDand_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  apply BDDand_preserves_nodes.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  assumption.  assumption.
Qed.

Lemma BDDand_keeps_neg_memo_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 BDDneg_memo_OK_2 (fst (BDDand cfg negm orm node1 node2))
   (fst (snd (snd (BDDand cfg negm orm node1 node2)))).
Proof.

(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.


(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) negm''' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace negm''' with (snd (snd (BDDneg cfg''' negm'' node))).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@snd ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq BDDneg_memo (@snd ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) negm' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.



(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.

Qed.

Lemma BDDand_keeps_or_memo_OK :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 BDDor_memo_OK (fst (BDDand cfg negm orm node1 node2))
   (snd (snd (snd (BDDand cfg negm orm node1 node2)))).
Proof.

(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.


(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.




(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.

Qed.

Definition bool_fun_and (bf1 bf2 : bool_fun) : bool_fun :=
  fun vb : var_binding => bf1 vb && bf2 vb.

Lemma bool_fun_and_is_neg_or_neg_neg :
 forall bf1 bf2 : bool_fun,
 bool_fun_eq (bool_fun_and bf1 bf2)
   (bool_fun_neg (bool_fun_or (bool_fun_neg bf1) (bool_fun_neg bf2))).
Proof.
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold bool_fun_eq, bool_fun_neg, bool_fun_or, bool_fun_and in |- *.  unfold bool_fun_eval in |- *.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim (bf1 vb).  elim (bf2 vb).  reflexivity.  reflexivity.  reflexivity.
Qed.

Lemma BDDand_is_and :
 forall (cfg : BDDconfig) (negm : BDDneg_memo) (orm : BDDor_memo)
   (node1 node2 : ad),
 BDDconfig_OK cfg ->
 BDDneg_memo_OK_2 cfg negm ->
 BDDor_memo_OK cfg orm ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 bool_fun_eq
   (bool_fun_of_BDD (fst (BDDand cfg negm orm node1 node2))
      (fst (snd (BDDand cfg negm orm node1 node2))))
   (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)).
Proof.

(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  intros.  unfold BDDand in |- *.  elim (prod_sum _ _ (BDDneg cfg negm node1)).  intros cfg' H4.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H4; clear H4.  intro.  elim x; clear x.  intros node1' negm' H4.  rewrite H4.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'', p) := BDDneg cfg' negm' node2 in let (node2', negm'') := p in let (cfg''', p0) := BDDor cfg'' orm node1' node2' in let (node, orm') := p0 in let (cfg'''', p1) := BDDneg cfg''' negm'' node in let (node', negm''') := p1 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim (prod_sum _ _ (BDDneg cfg' negm' node2)).  intros cfg'' H5.  elim H5; clear H5.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intro.  elim x; clear x.  intros node2' negm'' H5.  rewrite H5.  elim (prod_sum _ _ (BDDor cfg'' orm node1' node2')).
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  intros cfg''' H6.  elim H6; clear H6.  intro.  elim x; clear x.  intros node orm' H6.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg''', p) := BDDor cfg'' orm node1' node2' in let (node, orm') := p in let (cfg'''', p0) := BDDneg cfg''' negm'' node in let (node', negm''') := p0 in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  rewrite H6.  elim (prod_sum _ _ (BDDneg cfg''' negm'' node)).  intros cfg'''' H7.
(* Goal: forall (x : prod ad BDDneg_memo) (_ : @eq (prod BDDconfig (prod ad BDDneg_memo)) (BDDneg cfg''' negm'' node) (@pair BDDconfig (prod ad BDDneg_memo) cfg'''' x)), bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (let (cfg'''', p) := BDDneg cfg''' negm'' node in let (node', negm''') := p in @pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  elim H7; clear H7.  intro.  elim x; clear x.  intros node' negm''' H7.  rewrite H7.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))) (@fst ad (prod BDDneg_memo BDDor_memo) (@snd BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) (@pair BDDconfig (prod ad (prod BDDneg_memo BDDor_memo)) cfg'''' (@pair ad (prod BDDneg_memo BDDor_memo) node' (@pair BDDneg_memo BDDor_memo negm''' orm')))))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
  simpl in |- *.  cut (BDDconfig_OK cfg').  cut (config_node_OK cfg' node1').  cut (config_node_OK cfg' node2).
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg' negm').  cut (BDDor_memo_OK cfg' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg'').  cut (config_node_OK cfg'' node2').  cut (config_node_OK cfg'' node1').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDneg_memo_OK_2 cfg'' negm'').  cut (BDDor_memo_OK cfg'' orm).  intros.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDconfig_OK cfg''').  cut (config_node_OK cfg''' node).  cut (BDDneg_memo_OK_2 cfg''' negm'').
(* Goal: forall (_ : BDDor_memo_OK cfg''' orm') (_ : BDDneg_memo_OK_2 cfg''' negm'') (_ : config_node_OK cfg''' node) (_ : BDDconfig_OK cfg'''), bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  cut (BDDor_memo_OK cfg''' orm').  intros.



apply
 bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfg''' node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'''' node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'''' with (fst (BDDneg cfg''' negm'' node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) node') (bool_fun_neg (bool_fun_of_BDD cfg''' node)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg''' negm'' node)) cfg'''' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg''' node)) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace node' with (fst (snd (BDDneg cfg''' negm'' node))).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)))) (bool_fun_neg (bool_fun_of_BDD cfg' node2)) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2))) node2' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg' node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_is_neg.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H7; reflexivity.

apply
 bool_fun_eq_trans
  with
    (bf2 := bool_fun_neg
              (bool_fun_or (bool_fun_of_BDD cfg'' node1')
                 (bool_fun_of_BDD cfg'' node2'))).
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_eq_neg_1.
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) (@fst ad BDDor_memo (@snd BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')))) (bool_fun_or (bool_fun_of_BDD cfg'' node1') (bool_fun_of_BDD cfg'' node2')) *)
(* Goal: @eq ad (@fst ad BDDor_memo (@snd BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2'))) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_of_BDD cfg'' node1') (bool_fun_of_BDD cfg'' node2'))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDor_is_or.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H6; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H6; reflexivity.

apply
 bool_fun_eq_trans
  with
    (bf2 := bool_fun_neg
              (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1))
                 (bool_fun_neg (bool_fun_of_BDD cfg node2)))).
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_eq_neg_1.
(* Goal: bool_fun_eq (bool_fun_or (bool_fun_of_BDD cfg'' node1') (bool_fun_of_BDD cfg'' node2')) (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2))) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_or_preserves_eq.
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'' node1') (bool_fun_neg (bool_fun_of_BDD cfg node1)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD cfg'' node2') (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_eq_trans with (bf2 := bool_fun_of_BDD cfg' node1').
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node2) (bool_fun_of_BDD cfg node2) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_preserves_bool_fun.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H5; reflexivity.

(* Goal: BDDconfig_OK cfg' *)
replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
replace node1' with (fst (snd (BDDneg cfg negm node1))).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)))) (bool_fun_neg (bool_fun_of_BDD cfg' node2)) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2))) node2' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg' node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_is_neg.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H4; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H4; reflexivity.

apply
 bool_fun_eq_trans with (bf2 := bool_fun_neg (bool_fun_of_BDD cfg' node2)).
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) node2' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
replace node2' with (fst (snd (BDDneg cfg' negm' node2))).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)))) (bool_fun_neg (bool_fun_of_BDD cfg' node2)) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2))) node2' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD cfg' node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_is_neg.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H5; reflexivity.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H5; reflexivity.

(* Goal: BDDconfig_OK cfg' *)
replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node2)) (bool_fun_neg (bool_fun_of_BDD cfg node2)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_eq_neg_1.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) node2) (bool_fun_of_BDD cfg node2) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply BDDneg_preserves_bool_fun.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
assumption.

(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
rewrite H4; reflexivity.

(* Goal: bool_fun_eq (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_eq_symm.
(* Goal: bool_fun_eq (bool_fun_and (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)) (bool_fun_neg (bool_fun_or (bool_fun_neg (bool_fun_of_BDD cfg node1)) (bool_fun_neg (bool_fun_of_BDD cfg node2)))) *)
(* Goal: BDDor_memo_OK cfg''' orm' *)
(* Goal: BDDneg_memo_OK_2 cfg''' negm'' *)
(* Goal: config_node_OK cfg''' node *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
apply bool_fun_and_is_neg_or_neg_neg.


(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).  replace orm' with (snd (snd (BDDor cfg'' orm node1' node2'))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) node *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDor_memo) (BDDor cfg'' orm node1' node2')) cfg''' *)
(* Goal: BDDconfig_OK cfg''' *)
(* Goal: BDDor_memo_OK cfg'' orm *)
(* Goal: BDDneg_memo_OK_2 cfg'' negm'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node with (fst (snd (BDDor cfg'' orm node1' node2'))).  apply BDDor_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H6; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg''' with (fst (BDDor cfg'' orm node1' node2')).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDor_keeps_config_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H6; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_or_memo_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: BDDneg_memo_OK_2 (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) negm'' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg' negm' node2)) cfg'' *)
(* Goal: config_node_OK cfg'' node1' *)
(* Goal: config_node_OK cfg'' node2' *)
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace negm'' with (snd (snd (BDDneg cfg' negm' node2))).  apply BDDneg_keeps_neg_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.
(* Goal: BDDconfig_OK cfg'' *)
(* Goal: BDDor_memo_OK cfg' orm *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  apply BDDneg_keeps_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg'' with (fst (BDDneg cfg' negm' node2)).  replace node2' with (fst (snd (BDDneg cfg' negm' node2))).  apply BDDneg_node_OK.  assumption.  assumption.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  rewrite H5; reflexivity.  rewrite H5; reflexivity.  replace cfg'' with (fst (BDDneg cfg' negm' node2)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_config_OK.  assumption.  assumption.  assumption.  rewrite H5; reflexivity.

(* Goal: BDDor_memo_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) orm *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDneg_memo_OK_2 cfg' negm' *)
(* Goal: config_node_OK cfg' node2 *)
(* Goal: config_node_OK cfg' node1' *)
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_or_memo_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  replace negm' with (snd (snd (BDDneg cfg negm node1))).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_neg_memo_OK.  assumption.  assumption.  assumption.  rewrite H4; reflexivity.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  apply BDDneg_keeps_node_OK.  assumption.  assumption.  assumption.  assumption.
(* Goal: @eq bool (andb false (bf2 vb)) (negb (orb (negb false) (negb (bf2 vb)))) *)
  rewrite H4; reflexivity.  replace cfg' with (fst (BDDneg cfg negm node1)).
(* Goal: config_node_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) *)
(* Goal: @eq ad (@fst ad BDDneg_memo (@snd BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1))) node1' *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
(* Goal: BDDconfig_OK cfg' *)
  replace node1' with (fst (snd (BDDneg cfg negm node1))).  apply BDDneg_node_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.  rewrite H4; reflexivity.
(* Goal: BDDconfig_OK (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  replace cfg' with (fst (BDDneg cfg negm node1)).  apply BDDneg_keeps_config_OK.
(* Goal: config_node_OK cfg node1 *)
(* Goal: @eq BDDconfig (@fst BDDconfig (prod ad BDDneg_memo) (BDDneg cfg negm node1)) cfg' *)
  assumption.  assumption.  assumption.  rewrite H4; reflexivity.

Qed.