(* 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.

Lemma bool_fun_one_zero_eq : ~ bool_fun_eq bool_fun_one bool_fun_zero.
Proof.
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_of_BDD cfg BDDzero)) *)
  unfold bool_fun_eq, bool_fun_zero, bool_fun_one in |- *.  unfold not in |- *.  intro H.  unfold bool_fun_eval in H.
(* Goal: False *)
  cut (true = false).  intro; discriminate.  apply H.  exact (fun x : BDDvar => true).
Qed.

Lemma bool_fun_zero_one_eq : ~ bool_fun_eq bool_fun_zero bool_fun_one.
Proof.
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_of_BDD cfg BDDzero)) *)
  unfold bool_fun_eq, bool_fun_zero, bool_fun_one in |- *.  unfold not in |- *.  intro H.  unfold bool_fun_eval in H.
(* Goal: forall _ : @eq bool true false, and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) false *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  cut (false = true).  intro; discriminate.  apply H.  exact (fun x : BDDvar => true).
Qed.

Definition augment (vb : var_binding) (x : BDDvar) 
  (b : bool) (y : BDDvar) := if BDDvar_eq x y then b else vb y.

Definition bool_fun_restrict (bf : bool_fun) (x : BDDvar) 
  (b : bool) (vb : var_binding) := bool_fun_eval bf (augment vb x b).

Lemma bool_fun_restrict_zero :
 forall (x : BDDvar) (b : bool),
 bool_fun_eq (bool_fun_restrict bool_fun_zero x b) bool_fun_zero. 
Proof.
(* Goal: forall (x : BDDvar) (b : bool), bool_fun_eq (bool_fun_restrict bool_fun_one x b) bool_fun_one *)
  intros x b.  unfold bool_fun_eq, bool_fun_restrict, bool_fun_zero, bool_fun_one in |- *.
(* Goal: forall vb : var_binding, @eq bool (bool_fun_eval (fun vb0 : var_binding => bool_fun_eval (fun _ : var_binding => true) (augment vb0 x b)) vb) (bool_fun_eval (fun _ : var_binding => true) vb) *)
  intros vb.  unfold bool_fun_eval, augment in |- *.  reflexivity.
Qed.

Lemma bool_fun_restrict_one :
 forall (x : BDDvar) (b : bool),
 bool_fun_eq (bool_fun_restrict bool_fun_one x b) bool_fun_one.
Proof.
(* Goal: forall (x : BDDvar) (b : bool), bool_fun_eq (bool_fun_restrict bool_fun_one x b) bool_fun_one *)
  intros x b.  unfold bool_fun_eq, bool_fun_restrict, bool_fun_zero, bool_fun_one in |- *.
(* Goal: forall vb : var_binding, @eq bool (bool_fun_eval (fun vb0 : var_binding => bool_fun_eval (fun _ : var_binding => true) (augment vb0 x b)) vb) (bool_fun_eval (fun _ : var_binding => true) vb) *)
  intros vb.  unfold bool_fun_eval, augment in |- *.  reflexivity.
Qed.

Lemma bool_fun_restrict_eq :
 forall (bf bf' : bool_fun) (x : BDDvar) (b : bool),
 bool_fun_eq bf bf' ->
 bool_fun_eq (bool_fun_restrict bf x b) (bool_fun_restrict bf' x b).
Proof.
(* Goal: forall (bf bf' : bool_fun) (x : BDDvar) (b : bool) (_ : bool_fun_eq bf bf'), bool_fun_eq (bool_fun_restrict bf x b) (bool_fun_restrict bf' x b) *)
  intros bf bf' x b H.  unfold bool_fun_eq in |- *.  unfold bool_fun_restrict in |- *.  unfold bool_fun_eval at 1 3 in |- *.
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  intro vb.  apply H.
Qed.

Definition var_binding_eq (vb vb' : var_binding) :=
  forall x : BDDvar, vb x = vb' x.

Definition bool_fun_ext (bf : bool_fun) :=
  forall vb vb' : var_binding,
  var_binding_eq vb vb' -> bool_fun_eval bf vb = bool_fun_eval bf vb'.

Lemma bool_fun_of_BDD_1_ext :
 forall (bound : nat) (cfg : BDDconfig) (node : ad),
 bool_fun_ext (bool_fun_of_BDD_1 cfg node bound). 
Proof.
  simple induction bound.  intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  clear y.
  intros share counter.  intros node.  simpl in |- *.  elim (MapGet (BDDvar * (ad * ad)) bs node). Focus 2.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim (Neqb node BDDzero).  unfold bool_fun_ext in |- *.  unfold bool_fun_eval, bool_fun_zero in |- *; reflexivity.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_ext in |- *.  unfold bool_fun_eval, bool_fun_one in |- *; reflexivity.
  unfold bool_fun_ext in |- *.  unfold bool_fun_eval in |- *.  unfold bool_fun_zero in |- *.  intro a.
(* Goal: forall (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (n : nat) (node : ad) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
  intro vb.  intro vb'.  intro H.  elim a.  intros y y0.  elim y0.  reflexivity. intro n.
(* Goal: forall (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (n : nat) (node : ad) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
  intro H.  intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  clear y.  intros share counter.
  intros node.  simpl in |- *.  elim (MapGet (BDDvar * (ad * ad)) bs node).  Focus 2. elim (Neqb node BDDzero).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_ext, bool_fun_zero in |- *.  unfold bool_fun_eval in |- *; reflexivity.  
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_ext, bool_fun_one in |- *.  unfold bool_fun_eval in |- *; reflexivity.  intros a.
  elim a.  intros y y0.  elim y0. intros y1 y2.  cut (bool_fun_ext (bool_fun_of_BDD_1 (bs, (share, counter)) y2 n)).
(* Goal: forall _ : @eq BDDvar x x0, @eq bool b (vb x0) *)
(* Goal: @eq BDDvar x x0 *)
(* Goal: forall _ : @eq bool (BDDvar_eq x x0) false, @eq bool (if BDDvar_eq x x0 then b else vb x0) (vb x0) *)
  intro H0.  cut (bool_fun_ext (bool_fun_of_BDD_1 (bs, (share, counter)) y1 n)).  intro H1.
  unfold bool_fun_ext in |- *.  intros vb vb' H2.  unfold bool_fun_eval in |- *.  unfold bool_fun_ext in H0, H1.
  unfold bool_fun_eval in H0, H1.  rewrite (H1 vb vb' H2).  rewrite (H0 vb vb' H2).
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  unfold var_binding_eq in H2.  rewrite (H2 y).  reflexivity.  apply H.  apply H.
Qed.

Lemma bool_fun_of_BDD_ext :
 forall (cfg : BDDconfig) (node : ad),
 bool_fun_ext (bool_fun_of_BDD cfg node).
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad), bool_fun_ext (bool_fun_of_BDD cfg node) *)
  unfold bool_fun_of_BDD in |- *.  intros cfg node.  apply bool_fun_of_BDD_1_ext.
Qed.

Lemma augment_eq :
 forall (vb : var_binding) (x : BDDvar) (b : bool),
 vb x = b -> var_binding_eq (augment vb x b) vb.
Proof.
(* Goal: forall (vb : var_binding) (x : BDDvar) (b : bool) (_ : @eq bool (vb x) b), var_binding_eq (augment vb x b) vb *)
  unfold var_binding_eq in |- *.  intros vb x b H x0.  unfold augment in |- *.  elim (sumbool_of_bool (BDDvar_eq x x0)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro y.  rewrite y.  cut (x = x0).  intro H0.  rewrite <- H0.  rewrite H; reflexivity.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply Neqb_complete.  exact y.  intro y.  rewrite y.  reflexivity.
Qed.

Definition bool_fun_independent (bf : bool_fun) (x : BDDvar) :=
  forall vb : var_binding,
  bool_fun_eval bf (augment vb x true) =
  bool_fun_eval bf (augment vb x false).

Lemma bool_fun_independent_lemma :
 forall (bf : bool_fun) (x : BDDvar) (vb : var_binding) (b : bool),
 bool_fun_ext bf ->
 bool_fun_independent bf x ->
 bool_fun_eval bf (augment vb x b) = bool_fun_eval bf vb. 
Proof.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  intros bf x vb b H H0.  elim (sumbool_of_bool (vb x)).  intro y.  elim b.  cut (var_binding_eq (augment vb x true) vb).
(* Goal: forall (_ : @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true) (vb : var_binding), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (if if N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then false else vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  intro H1.  rewrite (H (augment vb x true) vb H1).  cut (bool_fun_eval bf (augment vb x true) = bool_fun_eval bf vb).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eval in |- *.  intro H2.  reflexivity.  rewrite (H (augment vb x true) vb H1).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  apply augment_eq.  assumption.  rewrite <- (H0 vb).  cut (var_binding_eq (augment vb x true) vb).
(* Goal: forall (_ : @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true) (vb : var_binding), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (if if N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then false else vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  intro H1.  rewrite (H (augment vb x true) vb H1).  cut (bool_fun_eval bf (augment vb x true) = bool_fun_eval bf vb).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eval in |- *.  intro H2.  reflexivity.  rewrite (H (augment vb x true) vb H1).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  apply augment_eq.  assumption.  intro y.  elim b.  cut (var_binding_eq (augment vb x false) vb).
(* Goal: forall (_ : @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true) (vb : var_binding), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (if if N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then false else vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  intro H1.  cut (bool_fun_eval bf (augment vb x false) = bool_fun_eval bf vb).
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  intro H2.  rewrite <- H2.  apply H0.  apply H.  assumption.  apply augment_eq.
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  assumption.  cut (var_binding_eq (augment vb x false) vb).  intro H1.  apply H.
(* Goal: var_binding_eq (augment vb x false) vb *)
  assumption.  apply augment_eq.  assumption.
Qed.

Lemma bool_fun_independent_zero :
 forall (cfg : BDDconfig) (x : BDDvar),
 BDDconfig_OK cfg -> bool_fun_independent (bool_fun_of_BDD cfg BDDzero) x.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))), bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDone) x *)
  intros x H.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_independent in |- *.  intro vb.  unfold bool_fun_eval, bool_fun_zero in |- *.  reflexivity.
Qed.

Lemma bool_fun_independent_one :
 forall (cfg : BDDconfig) (x : BDDvar),
 BDDconfig_OK cfg -> bool_fun_independent (bool_fun_of_BDD cfg BDDone) x.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))), bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDone) x *)
  intros x H.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_independent in |- *.  intro vb.  unfold bool_fun_eval, bool_fun_one in |- *.  reflexivity.
Qed.

Lemma in_dom_is_internal :
 forall (cfg : BDDconfig) (node : ad),
 in_dom _ node (fst cfg) = true -> is_internal_node cfg node.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
  intros node H.  elim (option_sum _ (MapGet _ (fst (bs, (share, counter))) node)).  intros y.
(* Goal: @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@None (prod BDDvar (prod ad ad))), @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x) Lt *)
(* Goal: node_OK bs (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  elim y. intro x.  elim x. intro y0. intro y1.  elim y1. intros y2 y3 y4.  split with y0; split with y2; split with y3; assumption.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  intro y.  unfold in_dom in H.  rewrite y in H.  discriminate H.
Qed.

Lemma internal_node_lemma :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 Neqb (low cfg node) (high cfg node) = false /\
 BDDbounded (fst cfg) (low cfg node) (var cfg node) /\
 BDDbounded (fst cfg) (high cfg node) (var cfg node).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
  intros node H H0.  elim H.  intros H1 H2.  elim H1.  intros H3 H4.  inversion H0.  inversion H5.
(* Goal: @eq ad node1 node2 *)
  inversion H6.  cut (BDD_OK bs node).  unfold BDD_OK in |- *.  unfold BDDordered in |- *.  simpl in H7; rewrite H7.
(* Goal: and (@eq bool (N.eqb match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => r | None => N0 end) false) (and (BDDbounded (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => x | None => BDDzero end) (BDDbounded (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => r | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => x | None => BDDzero end)) *)
(* Goal: BDD_OK bs node *)
  intro H8.  unfold var, high, low in |- *.  simpl in |- *.  rewrite H7.  cut
   (node = BDDzero \/
    node = BDDone \/
    (exists x' : BDDvar,
       (exists l' : BDDvar,
          (exists r' : BDDvar,
             MapGet _ bs node = Some (x', (l', r')) /\
             BDDcompare x' (ad_S x) = Datatypes.Lt /\
             Neqb l' r' = false /\
             BDDbounded bs l' x' /\ BDDbounded bs r' x')))).
(* Goal: forall _ : or (@eq ad node BDDzero) (or (@eq ad node BDDone) (@ex BDDvar (fun x' : BDDvar => @ex BDDvar (fun l' : BDDvar => @ex BDDvar (fun r' : BDDvar => and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs node) (@Some (prod BDDvar (prod BDDvar BDDvar)) (@pair BDDvar (prod BDDvar BDDvar) x' (@pair BDDvar BDDvar l' r')))) (and (@eq comparison (BDDcompare x' (ad_S x)) Lt) (and (@eq bool (N.eqb l' r') false) (and (BDDbounded bs l' x') (BDDbounded bs r' x'))))))))), and (@eq bool (N.eqb x0 x1) false) (and (BDDbounded bs x0 x) (BDDbounded bs x1 x)) *)
(* Goal: or (@eq ad node BDDzero) (or (@eq ad node BDDone) (@ex BDDvar (fun x' : BDDvar => @ex BDDvar (fun l' : BDDvar => @ex BDDvar (fun r' : BDDvar => and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs node) (@Some (prod BDDvar (prod BDDvar BDDvar)) (@pair BDDvar (prod BDDvar BDDvar) x' (@pair BDDvar BDDvar l' r')))) (and (@eq comparison (BDDcompare x' (ad_S x)) Lt) (and (@eq bool (N.eqb l' r') false) (and (BDDbounded bs l' x') (BDDbounded bs r' x'))))))))) *)
(* Goal: BDD_OK bs node *)
  intros H9.  elim H9; intros.  rewrite H10 in H7; rewrite H3 in H7; discriminate.  
(* Goal: and (@eq bool (N.eqb x0 x1) false) (and (BDDbounded bs x0 x) (BDDbounded bs x1 x)) *)
(* Goal: or (@eq ad node BDDzero) (or (@eq ad node BDDone) (@ex BDDvar (fun x' : BDDvar => @ex BDDvar (fun l' : BDDvar => @ex BDDvar (fun r' : BDDvar => and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs node) (@Some (prod BDDvar (prod BDDvar BDDvar)) (@pair BDDvar (prod BDDvar BDDvar) x' (@pair BDDvar BDDvar l' r')))) (and (@eq comparison (BDDcompare x' (ad_S x)) Lt) (and (@eq bool (N.eqb l' r') false) (and (BDDbounded bs l' x') (BDDbounded bs r' x'))))))))) *)
(* Goal: BDD_OK bs node *)
  elim H10; intros.  rewrite H11 in H7; rewrite (proj1 H4) in H7; discriminate.
(* Goal: @eq ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter'))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  inversion H11.  inversion H12.  inversion H13.  inversion H14.  rewrite H7 in H15.
(* Goal: and (@eq bool (N.eqb x0 x1) false) (and (BDDbounded bs x0 x) (BDDbounded bs x1 x)) *)
(* Goal: or (@eq ad node BDDzero) (or (@eq ad node BDDone) (@ex BDDvar (fun x' : BDDvar => @ex BDDvar (fun l' : BDDvar => @ex BDDvar (fun r' : BDDvar => and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs node) (@Some (prod BDDvar (prod BDDvar BDDvar)) (@pair BDDvar (prod BDDvar BDDvar) x' (@pair BDDvar BDDvar l' r')))) (and (@eq comparison (BDDcompare x' (ad_S x)) Lt) (and (@eq bool (N.eqb l' r') false) (and (BDDbounded bs l' x') (BDDbounded bs r' x'))))))))) *)
(* Goal: BDD_OK bs node *)
  injection H15.  intros H17 H18 H19.  rewrite <- H17 in H16.  rewrite <- H18 in H16.  rewrite <- H19 in H16.
(* Goal: config_node_OK cfg node *)
  exact (proj2 H16).  apply BDDbounded_lemma.  assumption.  apply (proj2 H4).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold in_dom in |- *; simpl in H7; rewrite H7; reflexivity.
Qed.

Lemma high_bounded :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 BDDbounded (fst cfg) (high cfg node) (var cfg node).
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
intros cfg node H H0.  exact (proj2 (proj2 (internal_node_lemma cfg node H H0))).
Qed.

Lemma low_bounded :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 BDDbounded (fst cfg) (low cfg node) (var cfg node).
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
intros cfg node H H0.  exact (proj1 (proj2 (internal_node_lemma cfg node H H0))).
Qed.

Lemma high_OK :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node -> config_node_OK cfg (high cfg node).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
  intros node H H0.  inversion H0.  inversion H1.  inversion H2.  unfold high in |- *.  rewrite H3.
  cut
   (BDDbounded (fst (bs, (share, counter)))
      (high (bs, (share, counter)) node) (var (bs, (share, counter)) node)).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) n0 *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  unfold var, high in |- *.  rewrite H3.  intro H4.  unfold config_node_OK in |- *.  apply BDDbounded_node_OK with (n := x).
(* Goal: config_node_OK cfg node *)
  assumption.  apply high_bounded.  assumption.  assumption.  
Qed.

Lemma low_OK :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node -> config_node_OK cfg (low cfg node).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
  intros node H H0.  inversion H0.  inversion H1.  inversion H2.  unfold low in |- *.  rewrite H3.
  cut
   (BDDbounded (fst (bs, (share, counter))) (low (bs, (share, counter)) node)
      (var (bs, (share, counter)) node)).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) n0 *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  unfold var, low in |- *.  rewrite H3.  intro H4.  unfold config_node_OK in |- *.  apply BDDbounded_node_OK with (n := x).
(* Goal: config_node_OK cfg node *)
  assumption.  apply low_bounded.  assumption.  assumption.
Qed.

Lemma low_high_neq :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node -> Neqb (low cfg node) (high cfg node) = false.
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
  intros cfg node H H0.  exact (proj1 (internal_node_lemma cfg node H H0)).
Qed.

Lemma BDDvar_independent_1 :
 forall (cfg : BDDconfig) (n : nat) (node : ad) (x : BDDvar),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 n = nat_of_N (var cfg node) ->
 BDDcompare (var cfg node) x = Datatypes.Lt ->
 bool_fun_independent (bool_fun_of_BDD cfg node) x.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (n : nat) (node : ad) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
  intro n.  apply
   lt_wf_ind
    with
      (P := fun n : nat =>
            forall (node : ad) (x : BDDvar),
            BDDconfig_OK (bs, (share, counter)) ->
            is_internal_node (bs, (share, counter)) node ->
            n = nat_of_N (var (bs, (share, counter)) node) ->
            BDDcompare (var (bs, (share, counter)) node) x = Datatypes.Lt ->
            bool_fun_independent
              (bool_fun_of_BDD (bs, (share, counter)) node) x).
(* Goal: forall (n : nat) (_ : forall (m : nat) (_ : lt m n) (node : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat m (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (_ : @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) x) Lt), bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) x) (node : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (_ : @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) x) Lt), bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) x *)
  intros n0 H node x H0 H1 H2 H3.  cut
   (bool_fun_independent
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node)) x).
  cut
   (bool_fun_independent
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node)) x).
(* Goal: forall (_ : @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb)) (_ : @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb)), @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  intros H4 H5.  rewrite
   (proj2 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H0)) node
      H1).
(* Goal: forall vb : var_binding, @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
  unfold bool_fun_independent in |- *.  unfold bool_fun_eval in |- *.  intro vb.  unfold bool_fun_independent in H4, H5.
(* Goal: @eq ad node1 node2 *)
  unfold bool_fun_eval in H4, H5.  inversion H1.  inversion H6.  inversion H7.
(* Goal: @eq bool (if augment vb x true (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb x true) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb x true)) (if augment vb x false (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb x false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb x false)) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  unfold var, high, low in |- *.  rewrite H8.  unfold augment at 1 4 in |- *.  cut (BDDvar_eq x x0 = false).
(* Goal: forall _ : or (@eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro H9.  rewrite H9.  unfold var, high, low in H5, H4.  rewrite H8 in H4.  rewrite H8 in H5.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite (H4 vb).  rewrite (H5 vb).  reflexivity.  unfold BDDvar_eq in |- *.  cut (Neqb x x0 <> true).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim (Neqb x x0).  intro H9.  absurd (true = true).  assumption.  reflexivity.  reflexivity.
(* Goal: not (@eq bool (N.eqb x x0) true) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  unfold not in |- *.  intro H9.  unfold var in H3.  rewrite H8 in H3.  cut (nat_of_N x0 < nat_of_N x).
(* Goal: forall _ : lt (N.to_nat x0) (N.to_nat x), False *)
(* Goal: lt (N.to_nat x0) (N.to_nat x) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  cut (x = x0).  intro H10.  rewrite H10.  exact (lt_irrefl (nat_of_N x0)).  apply Neqb_complete.
(* Goal: config_node_OK cfg node *)
  assumption.  apply BDDcompare_lt.  assumption.  cut (node_OK bs (high (bs, (share, counter)) node)).
(* Goal: config_node_OK cfg node *)
  intro H4.  elim H4.  intro H5.  rewrite H5.  apply bool_fun_independent_zero.  assumption.
(* Goal: config_node_OK cfg node *)
  intro H5.  elim H5; intro H6.  rewrite H6.  apply bool_fun_independent_one.  assumption.
  apply
   H
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (high (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H2.  apply BDDcompare_lt.  apply BDDvar_ordered_high.  assumption.  
(* Goal: config_node_OK cfg node *)
  assumption.  unfold is_internal_node in |- *.  elim
   (option_sum _
      (MapGet (BDDvar * (ad * ad)) (fst (bs, (share, counter)))
         (high (bs, (share, counter)) node))).
(* Goal: @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@None (prod BDDvar (prod ad ad))), @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x) Lt *)
(* Goal: node_OK bs (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  intro y.  elim y.  intro x0.  elim x0. intro y0. intro y1.  elim y1. intro y2. intro y3.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  split with y0.  split with y2.  split with y3.  assumption.  intro y.  unfold in_dom in H6.
(* Goal: config_node_OK cfg node *)
  simpl in y.  rewrite y in H6.  discriminate H6.  assumption.  apply in_dom_is_internal.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  apply BDDcompare_trans with (y := var (bs, (share, counter)) node).
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_high.  assumption.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  exact (high_OK (bs, (share, counter)) node H0 H1).
(* Goal: forall _ : is_internal_node cfg (low cfg node), bool_fun_independent (bool_fun_of_BDD cfg (low cfg node)) (var cfg node) *)
(* Goal: is_internal_node cfg (low cfg node) *)
(* Goal: config_node_OK cfg (low cfg node) *)
  cut (node_OK bs (low (bs, (share, counter)) node)).  intro H4.  elim H4.  intro H5.
(* Goal: config_node_OK cfg node *)
  rewrite H5.  apply bool_fun_independent_zero.  assumption.  intro H5.  elim H5; intro H6.
(* Goal: config_node_OK cfg node *)
  rewrite H6.  apply bool_fun_independent_one.  assumption.  apply
   H
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (low (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H2.  apply BDDcompare_lt.  apply BDDvar_ordered_low.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  assumption.  apply in_dom_is_internal.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  apply BDDcompare_trans with (y := var (bs, (share, counter)) node).
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_low.  assumption.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  exact (low_OK (bs, (share, counter)) node H0 H1).
Qed.

Lemma BDDvar_independent_high :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 bool_fun_independent (bool_fun_of_BDD cfg (high cfg node)) (var cfg node).
Proof.
(* Goal: forall _ : @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  intros cfg node H H0.  cut (config_node_OK cfg (high cfg node)).  intros H1.  elim H1.  intro H2.
(* Goal: forall _ : @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  rewrite H2.  apply bool_fun_independent_zero.  assumption.  intro H2.  elim H2; intro.
(* Goal: config_node_OK cfg node *)
  rewrite H3; apply bool_fun_independent_one; assumption.  cut (is_internal_node cfg (high cfg node)).
(* Goal: forall _ : is_internal_node cfg (low cfg node), bool_fun_independent (bool_fun_of_BDD cfg (low cfg node)) (var cfg node) *)
(* Goal: is_internal_node cfg (low cfg node) *)
(* Goal: config_node_OK cfg (low cfg node) *)
  intro H4.  apply BDDvar_independent_1 with (n := nat_of_N (var cfg (high cfg node))).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  reflexivity.  apply BDDvar_ordered_high.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  assumption.  apply in_dom_is_internal.  assumption.
(* Goal: config_node_OK cfg node *)
  apply high_OK.  assumption.  assumption.
Qed.

Lemma BDDvar_independent_low :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 bool_fun_independent (bool_fun_of_BDD cfg (low cfg node)) (var cfg node).
Proof.
(* Goal: forall _ : @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  intros cfg node H H0.  cut (config_node_OK cfg (low cfg node)).  intros H1.  elim H1.  intro H2.
(* Goal: forall _ : @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb), @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
(* Goal: @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  rewrite H2.  apply bool_fun_independent_zero.  assumption.  intro H2.  elim H2; intro.
(* Goal: config_node_OK cfg node *)
  rewrite H3; apply bool_fun_independent_one; assumption.  cut (is_internal_node cfg (low cfg node)).
(* Goal: forall _ : is_internal_node cfg (low cfg node), bool_fun_independent (bool_fun_of_BDD cfg (low cfg node)) (var cfg node) *)
(* Goal: is_internal_node cfg (low cfg node) *)
(* Goal: config_node_OK cfg (low cfg node) *)
  intro H4.  apply BDDvar_independent_1 with (n := nat_of_N (var cfg (low cfg node))).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  reflexivity.  apply BDDvar_ordered_low.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  assumption.  apply in_dom_is_internal.  assumption.
(* Goal: config_node_OK cfg node *)
  apply low_OK.  assumption.  assumption.
Qed.

Lemma bool_fun_of_BDDzero :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg -> bool_fun_eq (bool_fun_of_BDD cfg BDDzero) bool_fun_zero.
Proof.
(* Goal: bool_fun_eq bf1 bf2 *)
  intros cfg H.  unfold bool_fun_eq in |- *.  unfold bool_fun_eval in |- *.  intro vb.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite (proj1 (bool_fun_of_BDD_semantics cfg H)).  reflexivity.
Qed.

Lemma bool_fun_of_BDDone :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg -> bool_fun_eq (bool_fun_of_BDD cfg BDDone) bool_fun_one.
Proof.
(* Goal: bool_fun_eq bf1 bf2 *)
  intros cfg H.  unfold bool_fun_eq in |- *.  unfold bool_fun_eval in |- *.  intro vb.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite (proj1 (proj2 (bool_fun_of_BDD_semantics cfg H))).  reflexivity.
Qed.

Lemma bool_fun_of_BDDhigh :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 bool_fun_eq (bool_fun_of_BDD cfg (high cfg node))
   (bool_fun_restrict (bool_fun_of_BDD cfg node) (var cfg node) true).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
  intros node H H0.  rewrite
   (proj2 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)) node
      H0).
(* Goal: bool_fun_eq bf1 bf2 *)
  unfold bool_fun_restrict in |- *.  unfold bool_fun_eval in |- *.  unfold bool_fun_eq in |- *.  unfold bool_fun_eval in |- *.
(* Goal: forall vb : var_binding, @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (if if BDDvar_eq (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then false else vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
  unfold augment at 1 in |- *.  unfold BDDvar_eq in |- *.  cut
   (Neqb (var (bs, (share, counter)) node) (var (bs, (share, counter)) node) =
    true).
(* Goal: forall vb : var_binding, @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
  intro H1.  rewrite H1.  intro vb.  cut
   (bool_fun_of_BDD (bs, (share, counter)) (high (bs, (share, counter)) node)
      (augment vb (var (bs, (share, counter)) node) true) =
    bool_fun_of_BDD (bs, (share, counter)) (high (bs, (share, counter)) node)
      vb).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro H2.  rewrite H2.  reflexivity.  change
    (bool_fun_eval
       (bool_fun_of_BDD (bs, (share, counter))
          (high (bs, (share, counter)) node))
       (augment vb (var (bs, (share, counter)) node) true) =
     bool_fun_eval
       (bool_fun_of_BDD (bs, (share, counter))
          (high (bs, (share, counter)) node)) vb) in |- *.
(* Goal: @eq bool (bool_fun_eval (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_eval (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  apply bool_fun_independent_lemma.  apply bool_fun_of_BDD_ext.  apply BDDvar_independent_high.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply Neqb_correct.
Qed.

Lemma bool_fun_of_BDDlow :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 bool_fun_eq (bool_fun_of_BDD cfg (low cfg node))
   (bool_fun_restrict (bool_fun_of_BDD cfg node) (var cfg node) false).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (node : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
  intros node H H0.  rewrite
   (proj2 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)) node
      H0).
(* Goal: bool_fun_eq bf1 bf2 *)
  unfold bool_fun_restrict in |- *.  unfold bool_fun_eval in |- *.  unfold bool_fun_eq in |- *.  unfold bool_fun_eval in |- *.
(* Goal: forall vb : var_binding, @eq bool (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) vb) (if if BDDvar_eq (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then false else vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) then bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) else bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) *)
  unfold augment at 1 in |- *.  unfold BDDvar_eq in |- *.  cut
   (Neqb (var (bs, (share, counter)) node) (var (bs, (share, counter)) node) =
    true).
(* Goal: forall vb : var_binding, @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
  intro H1.  rewrite H1.  intro vb.  cut
   (bool_fun_of_BDD (bs, (share, counter)) (low (bs, (share, counter)) node)
      (augment vb (var (bs, (share, counter)) node) false) =
    bool_fun_of_BDD (bs, (share, counter)) (low (bs, (share, counter)) node)
      vb).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro H2.  rewrite H2.  reflexivity.  change
    (bool_fun_eval
       (bool_fun_of_BDD (bs, (share, counter))
          (low (bs, (share, counter)) node))
       (augment vb (var (bs, (share, counter)) node) false) =
     bool_fun_eval
       (bool_fun_of_BDD (bs, (share, counter))
          (low (bs, (share, counter)) node)) vb) in |- *.
(* Goal: @eq bool (bool_fun_eval (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (augment vb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false)) (bool_fun_eval (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) vb) *)
(* Goal: @eq bool (N.eqb (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
  apply bool_fun_independent_lemma.  apply bool_fun_of_BDD_ext.  apply BDDvar_independent_low.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply Neqb_correct.
Qed.

Lemma internal_node_not_constant_1 :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg ->
 forall (n : nat) (node : ad),
 is_internal_node cfg node ->
 n = nat_of_N (var cfg node) ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_zero /\
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_one.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (n : nat) (node : ad) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
  intro H.  intro n.  apply
   lt_wf_ind
    with
      (P := fun n : nat =>
            forall node : ad,
            is_internal_node (bs, (share, counter)) node ->
            n = nat_of_N (var (bs, (share, counter)) node) ->
            ~
            bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node)
              bool_fun_zero /\
            ~
            bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node)
              bool_fun_one).
(* Goal: @eq ad node1 node2 *)
  intros n0 H0 node H1 H2.  inversion H1.  inversion H3.  inversion H4.  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node)).
  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node)).
(* Goal: forall _ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1, not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one *)
(* Goal: @eq ad node1 node2 *)
  intros H6 H7.  elim H6.  intro H8.  elim H7.  intro H9.  cut
   (Neqb (low (bs, (share, counter)) node)
      (high (bs, (share, counter)) node) = true).
(* Goal: forall _ : @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true, and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) true *)
(* Goal: forall _ : or (@eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
rewrite (low_high_neq (bs, (share, counter)) node H H1).
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro H10.  discriminate H10.  rewrite H8.  rewrite H9.  apply Neqb_correct.  intro H9.
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  elim H9; clear H9; intro.  cut
   (bool_fun_of_BDD (bs, (share, counter)) (high (bs, (share, counter)) node) =
    bool_fun_one).
  cut
   (bool_fun_of_BDD (bs, (share, counter)) (low (bs, (share, counter)) node) =
    bool_fun_zero).
  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node))
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) true)).
(* Goal: forall (_ : bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true)) (_ : @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero) (_ : @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intros H10 H11 H12.  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node))
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) false)).
(* Goal: forall _ : bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intros H13.  rewrite H12 in H10.  rewrite H11 in H13.  split; unfold not in |- *; intro.
  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) true)
      (bool_fun_restrict bool_fun_zero (var (bs, (share, counter)) node) true)).
(* Goal: forall _ : @eq bool true false, @eq ad node1 node2 *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) false *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H15.  cut
   (bool_fun_eq bool_fun_one
      (bool_fun_restrict bool_fun_zero (var (bs, (share, counter)) node) true)).
(* Goal: forall _ : bool_fun_eq bool_fun_zero (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false), False *)
(* Goal: bool_fun_eq bool_fun_zero (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro H16.  cut (bool_fun_eq bool_fun_one bool_fun_zero).  intro H17.  absurd (bool_fun_eq bool_fun_one bool_fun_zero).
(* Goal: config_node_OK cfg node *)
  exact bool_fun_one_zero_eq.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_zero
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_restrict_zero.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply bool_fun_restrict_eq.  assumption.  
  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) false)
      (bool_fun_restrict bool_fun_one (var (bs, (share, counter)) node) false)).
(* Goal: forall _ : @eq bool true false, @eq ad node1 node2 *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) false *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H15.  cut
   (bool_fun_eq bool_fun_zero
      (bool_fun_restrict bool_fun_one (var (bs, (share, counter)) node) false)).
(* Goal: forall _ : bool_fun_eq bool_fun_zero (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false), False *)
(* Goal: bool_fun_eq bool_fun_zero (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) (bool_fun_restrict bool_fun_one (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero *)
(* Goal: @eq bool_fun (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro H16.  cut (bool_fun_eq bool_fun_zero bool_fun_one).  intro H17.  absurd (bool_fun_eq bool_fun_zero bool_fun_one).
(* Goal: config_node_OK cfg node *)
  exact bool_fun_zero_one_eq.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_one
                (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_restrict_one.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_of_BDDlow.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply bool_fun_of_BDDhigh.  assumption.  assumption.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H8.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  rewrite H9.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  cut
   (~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node)) bool_fun_zero /\
    ~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node)) bool_fun_one).
(* Goal: forall _ : @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intro H10.  split; unfold not in |- *; intro.  apply (proj1 H10).  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_zero
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_zero.  apply (proj2 H10).
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_one
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_one.  
  apply
   H0
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (high (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H2.  apply BDDcompare_lt.  apply BDDvar_ordered_high.  assumption.  
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  apply in_dom_is_internal.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  intro H8.  elim H8; intro.  elim H7; intro.  split; unfold not in |- *; intro.
(* Goal: False *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  apply bool_fun_zero_one_eq.  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) false).
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_zero
                (var (bs, (share, counter)) node) false).
(* Goal: bool_fun_eq (bool_fun_restrict bool_fun_zero (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) bool_fun_zero *)
(* Goal: False *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  apply bool_fun_eq_symm.  apply bool_fun_restrict_zero.  apply bool_fun_restrict_eq.
(* Goal: config_node_OK cfg node *)
  apply bool_fun_eq_symm.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs, (share, counter))
                (low (bs, (share, counter)) node)).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_eq_symm.  apply bool_fun_of_BDDlow.  assumption.  assumption.
(* Goal: forall _ : @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) false, and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) false *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  rewrite H9.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq, bool_fun_one in |- *.  reflexivity.  apply bool_fun_zero_one_eq.
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs, (share, counter))
                (high (bs, (share, counter)) node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H10.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_one
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_one.  elim H10; intro.
  cut
   (Neqb (low (bs, (share, counter)) node)
      (high (bs, (share, counter)) node) = false).
(* Goal: forall _ : @eq bool true false, and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) false *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  rewrite H9.  rewrite H11.  rewrite (Neqb_correct BDDone).  intro; discriminate.  
(* Goal: config_node_OK cfg node *)
  apply low_high_neq.  assumption.  assumption.  cut
   (~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node)) bool_fun_zero /\
    ~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node)) bool_fun_one).
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) bool_fun_one)) *)
(* Goal: and (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_zero)) (not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) bool_fun_one)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro H12.  split; unfold not in |- *; intro.  apply (proj1 H12).  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_zero
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_zero.  apply (proj2 H12).
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_one
                (var (bs, (share, counter)) node) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_one.  apply
   H0
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (high (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H2.  apply BDDcompare_lt.  apply BDDvar_ordered_high.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  apply in_dom_is_internal.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  cut
   (~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node)) bool_fun_zero /\
    ~
    bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node)) bool_fun_one).
(* Goal: forall _ : @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intro H10.  split; unfold not in |- *; intro.  apply (proj1 H10).  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
         (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDlow.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_zero
                (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_zero.  apply (proj2 H10).
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node)
                (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDlow.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict bool_fun_one
                (var (bs, (share, counter)) node) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply bool_fun_restrict_one.  apply
   H0
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (low (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H2.  apply BDDcompare_lt.  apply BDDvar_ordered_low.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  apply in_dom_is_internal.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  apply low_OK.  assumption.  assumption.  apply high_OK.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  
Qed.

Lemma internal_node_not_constant :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_zero /\
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_one.
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
  intros cfg node H H0.  apply internal_node_not_constant_1 with (n := nat_of_N (var cfg node)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  reflexivity.
Qed.

Lemma bool_fun_neq_internal_zero :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDzero).
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
  intros cfg node H H0.  rewrite (proj1 (bool_fun_of_BDD_semantics cfg H)).
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_zero) *)
  exact (proj1 (internal_node_not_constant cfg node H H0)).
Qed.
 
Lemma bool_fun_neq_internal_one :
 forall (cfg : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone).
Proof.
(* Goal: forall (cfg : BDDconfig) (node : ad) (_ : BDDconfig_OK cfg) (_ : is_internal_node cfg node), not (bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_BDD cfg BDDone)) *)
  intros cfg node H H0.  rewrite (proj1 (proj2 (bool_fun_of_BDD_semantics cfg H))).
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg node) bool_fun_one) *)
  exact (proj2 (internal_node_not_constant cfg node H H0)).
Qed.

Lemma bool_fun_neq_zero_one :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg BDDzero) (bool_fun_of_BDD cfg BDDone).
Proof.
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_of_BDD cfg BDDzero)) *)
  intros cfg H.  unfold bool_fun_eq, bool_fun_zero, bool_fun_one in |- *.  unfold bool_fun_eval in |- *.
(* Goal: not (forall vb : var_binding, @eq bool (bool_fun_of_BDD cfg BDDone vb) (bool_fun_of_BDD cfg BDDzero vb)) *)
  rewrite (proj1 (bool_fun_of_BDD_semantics cfg H)).  rewrite (proj1 (proj2 (bool_fun_of_BDD_semantics cfg H))).
(* Goal: forall (bf1 bf2 : bool_fun) (_ : not (bool_fun_eq bf1 bf2)), not (bool_fun_eq bf2 bf1) *)
  unfold not in |- *; intros.  absurd (true = false).  unfold not in |- *; discriminate.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_zero, bool_fun_one in H0.  rewrite (H0 (fun x : BDDvar => true)).  reflexivity.
Qed.

Lemma bool_fun_neq_one_zero :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg ->
 ~ bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_of_BDD cfg BDDzero).
Proof.
(* Goal: not (bool_fun_eq (bool_fun_of_BDD cfg BDDone) (bool_fun_of_BDD cfg BDDzero)) *)
  intros cfg H.  unfold bool_fun_eq, bool_fun_zero, bool_fun_one in |- *.  unfold bool_fun_eval in |- *.
(* Goal: not (forall vb : var_binding, @eq bool (bool_fun_of_BDD cfg BDDone vb) (bool_fun_of_BDD cfg BDDzero vb)) *)
  rewrite (proj1 (bool_fun_of_BDD_semantics cfg H)).  rewrite (proj1 (proj2 (bool_fun_of_BDD_semantics cfg H))).
(* Goal: forall (bf1 bf2 : bool_fun) (_ : not (bool_fun_eq bf1 bf2)), not (bool_fun_eq bf2 bf1) *)
  unfold not in |- *; intros.  absurd (false = true).  unfold not in |- *; discriminate.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_zero, bool_fun_one in H0.  rewrite (H0 (fun x : BDDvar => true)).  reflexivity.
Qed.

Lemma bool_fun_neq_lemma :
 forall bf1 bf2 : bool_fun, ~ bool_fun_eq bf1 bf2 -> ~ bool_fun_eq bf2 bf1.
Proof.
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  unfold not in |- *; intros.  apply H.  apply bool_fun_eq_symm.  assumption.
Qed.

Lemma no_duplicate_node :
 forall (cfg : BDDconfig) (node1 node2 : ad),
 BDDconfig_OK cfg ->
 is_internal_node cfg node1 ->
 is_internal_node cfg node2 ->
 var cfg node1 = var cfg node2 ->
 high cfg node1 = high cfg node2 ->
 low cfg node1 = low cfg node2 -> node1 = node2.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: @eq ad node1 node2 *)
  intros node1 node2 H H0 H1 H2 H3 H4.  inversion H0.  inversion H5.  inversion H6.  inversion H1.  inversion H8.
(* Goal: @eq ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter'))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  inversion H9.  unfold var in H2; rewrite H7 in H2; rewrite H10 in H2.
(* Goal: @eq ad node1 node2 *)
  unfold high in H3; rewrite H7 in H3; rewrite H10 in H3.  unfold low in H4; rewrite H7 in H4; rewrite H10 in H4.
(* Goal: @eq ad node1 node2 *)
  cut (BDDshare_lookup share x x0 x1 = Some node1).  cut (BDDshare_lookup share x2 x3 x4 = Some node2).
(* Goal: forall (_ : BDDstate_OK bs) (_ : and (BDDsharing_OK bs share) (and (forall (a : ad) (_ : @eq bool (Nleb counter a) true), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@None (prod BDDvar (prod ad ad)))) (@eq bool (Nleb (ad_S (ad_S N0)) counter) true))), @eq (option ad) (BDDshare_lookup share x2 x3 x4) (@Some ad node2) *)
(* Goal: @eq (option ad) (BDDshare_lookup share x x0 x1) (@Some ad node1) *)
  intros H11 H12.  rewrite H2 in H12.  rewrite H3 in H12.  rewrite H4 in H12.  rewrite H11 in H12.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  injection H12.  intro H13.  rewrite H13; reflexivity.  elim H.  intros H11 H12.  apply (proj2 (proj1 H12 x2 x3 x4 node2)).
(* Goal: config_node_OK cfg node *)
  assumption.  elim H; intros.  apply (proj2 (proj1 H12 x x0 x1 node1)).
(* Goal: config_node_OK cfg node *)
assumption.
Qed.

Lemma BDDunique_1 :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg ->
 forall (n : nat) (node1 node2 : ad),
 n = max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2)) ->
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 bool_fun_eq (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2) ->
 node1 = node2.
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (n : nat) (node1 node2 : ad) (_ : @eq nat n (max (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)))) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (_ : bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)), @eq ad node1 node2 *)
  intros H n.  apply
   lt_wf_ind
    with
      (P := fun n : nat =>
            forall node1 node2 : ad,
            n =
            max (nat_of_N (var (bs, (share, counter)) node1))
              (nat_of_N (var (bs, (share, counter)) node2)) ->
            config_node_OK (bs, (share, counter)) node1 ->
            config_node_OK (bs, (share, counter)) node2 ->
            bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node1)
              (bool_fun_of_BDD (bs, (share, counter)) node2) -> 
            node1 = node2).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intros n0 H00.  intros node1 node2 H0 H1 H2 H3.  elim H1; intro.  elim H2; intro.  rewrite H4; rewrite H5; reflexivity.
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  elim H5; intro.  rewrite H4 in H3.  rewrite H6 in H3.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)) in H3.
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
    in H3.
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
  absurd (bool_fun_eq bool_fun_zero bool_fun_one).  exact bool_fun_zero_one_eq.
(* Goal: config_node_OK cfg node *)
  assumption.  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node2) bool_fun_zero).
(* Goal: forall _ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1, @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  cut (is_internal_node (bs, (share, counter)) node2).  intro H7.  exact
   (proj1 (internal_node_not_constant (bs, (share, counter)) node2 H H7)).
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  apply bool_fun_eq_trans with (bool_fun_of_BDD (bs, (share, counter)) node1).  apply bool_fun_eq_symm; assumption.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H4.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  elim H4; intro.  elim H2; intro.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_zero *)
(* Goal: @eq ad node1 node2 *)
  rewrite H5 in H3; rewrite H6 in H3.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)) in H3.
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
    in H3.
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
  absurd (bool_fun_eq bool_fun_one bool_fun_zero).  exact bool_fun_one_zero_eq.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  elim H6; intro.  rewrite H5; rewrite H7; reflexivity.
  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node2) bool_fun_one).
(* Goal: forall _ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1, not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one *)
(* Goal: @eq ad node1 node2 *)
  cut (is_internal_node (bs, (share, counter)) node2).  intro H8.  exact
   (proj2 (internal_node_not_constant (bs, (share, counter)) node2 H H8)).
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  rewrite H5 in H3.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
    in H3.
(* Goal: config_node_OK cfg node *)
  apply bool_fun_eq_symm.  assumption.  elim H2; intro.  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node1) bool_fun_zero).
(* Goal: forall _ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1, not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_zero) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_zero *)
(* Goal: @eq ad node1 node2 *)
  cut (is_internal_node (bs, (share, counter)) node1).  intro H7.  exact
   (proj1 (internal_node_not_constant (bs, (share, counter)) node1 H H7)).
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  rewrite H6 in H3.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)) in H3.
(* Goal: config_node_OK cfg node *)
  assumption.  elim H6; intro.  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) node1) bool_fun_one).
(* Goal: forall _ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1, not (bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) bool_fun_one *)
(* Goal: @eq ad node1 node2 *)
  cut (is_internal_node (bs, (share, counter)) node1).  intro H8.  exact
   (proj2 (internal_node_not_constant (bs, (share, counter)) node1 H H8)).
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  rewrite H7 in H3.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
    in H3.
(* Goal: config_node_OK cfg node *)
  assumption.  cut (is_internal_node (bs, (share, counter)) node1).  cut (is_internal_node (bs, (share, counter)) node2).
(* Goal: forall (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intros H8 H9.  elim
   (relation_sum
      (BDDcompare (var (bs, (share, counter)) node1)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
         (var (bs, (share, counter)) node2))); intro y.
(* Goal: forall (a : BDDvar) (b : prod ad ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) a b))), @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@None (prod BDDvar (prod ad ad))), @ex BDDvar (fun x : BDDvar => @ex ad (fun l : ad => @ex ad (fun r : ad => @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))))) *)
(* Goal: BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x) Lt *)
(* Goal: node_OK bs (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) x *)
  elim y; clear y; intro y0.  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node1)).
  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node2)).
  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node1)).
  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node2)).
(* Goal: forall (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)), @eq ad node1 node2 *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intros H10 H11 H12 H13.  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: forall (_ : bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2))) (_ : bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2))), @eq ad node1 node2 *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intros H14 H15.  cut (high (bs, (share, counter)) node1 = high (bs, (share, counter)) node2).
(* Goal: forall _ : @eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2), @eq ad node1 node2 *)
(* Goal: @eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  cut (low (bs, (share, counter)) node1 = low (bs, (share, counter)) node2).  intros H16 H17.
(* Goal: config_node_OK cfg node *)
  apply no_duplicate_node with (cfg := (bs, (share, counter))).  assumption.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply BDDcompare_eq; assumption.  assumption.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim H11; intro.  elim H10; intro.  rewrite H16; rewrite H17; reflexivity.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  elim H17; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H16; rewrite H18.  apply bool_fun_neq_zero_one.  assumption.  assumption.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_neq_lemma.  rewrite H16.  apply bool_fun_neq_internal_zero.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  assumption.  elim H16; intro.  elim H10; intro.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H17; rewrite H18.  apply bool_fun_neq_one_zero.  assumption.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim H18; intro.  rewrite H17; rewrite H19; reflexivity.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H17.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_one.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  assumption.  elim H10; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H18.  apply bool_fun_neq_internal_zero.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  elim H18; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H19.  apply bool_fun_neq_internal_one.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply
   H00
    with
      (m := max
              (nat_of_N
                 (var (bs, (share, counter))
                    (low (bs, (share, counter)) node1)))
              (nat_of_N
                 (var (bs, (share, counter))
                    (low (bs, (share, counter)) node2)))).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H0.  apply lt_max_1_2.  apply BDDcompare_lt.  apply BDDvar_ordered_low.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply in_dom_is_internal; assumption.  apply BDDcompare_lt.
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_low.  assumption.  apply in_dom_is_internal; assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  reflexivity.  assumption.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  elim H13; intro.  elim H12; intro.  rewrite H16; rewrite H17; reflexivity.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  elim H17; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H16; rewrite H18; apply bool_fun_neq_zero_one.  assumption.  assumption.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H16.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_zero.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  assumption.  elim H16; intro.  rewrite H17 in H15.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  elim H12; intro.  rewrite H18 in H15.  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) BDDone)
      (bool_fun_of_BDD (bs, (share, counter)) BDDzero)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply bool_fun_neq_one_zero.  assumption.  assumption.  elim H18; intro.  rewrite H17; rewrite H19; reflexivity.
  absurd
   (bool_fun_eq (bool_fun_of_BDD (bs, (share, counter)) BDDone)
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_one.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  elim H12; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H18.  apply bool_fun_neq_internal_zero.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  elim H18; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H19.  apply bool_fun_neq_internal_one.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply
   H00
    with
      (m := max
              (nat_of_N
                 (var (bs, (share, counter))
                    (high (bs, (share, counter)) node1)))
              (nat_of_N
                 (var (bs, (share, counter))
                    (high (bs, (share, counter)) node2)))).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H0.  apply lt_max_1_2.  apply BDDcompare_lt.  apply BDDvar_ordered_high.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply in_dom_is_internal.  assumption.  apply BDDcompare_lt.
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_high.  assumption.  apply in_dom_is_internal.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  reflexivity.  assumption.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node1) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDlow.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node2) false).
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) true) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) true) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  cut (var (bs, (share, counter)) node1 = var (bs, (share, counter)) node2).  intro H14.
(* Goal: config_node_OK cfg node *)
  rewrite H14.  apply bool_fun_restrict_eq.  assumption.  apply BDDcompare_eq.
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_eq_symm.  apply bool_fun_of_BDDlow.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node1) true).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node2) true).
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) true) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) true) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad node1 node2 *)
(* Goal: @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  cut (var (bs, (share, counter)) node1 = var (bs, (share, counter)) node2).  intro H14.
(* Goal: config_node_OK cfg node *)
  rewrite H14.  apply bool_fun_restrict_eq.  assumption.  apply BDDcompare_eq.
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_eq_symm.  apply bool_fun_of_BDDhigh.  assumption. 
(* Goal: config_node_OK cfg node *)
  assumption.  apply low_OK.  assumption.  assumption.  apply low_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply high_OK.  assumption.  assumption.  apply high_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node1)).
  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node2)).  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node1)).
  cut
(* Goal: forall (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)), @eq ad node1 node2 *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node2)).  intros H10 H11 H12 H13.
(* Goal: @eq ad node1 node2 *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad node1 node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  cut (low (bs, (share, counter)) node2 = high (bs, (share, counter)) node2).  intros H14.
  cut
   (Neqb (low (bs, (share, counter)) node2)
      (high (bs, (share, counter)) node2) = false).
(* Goal: forall _ : @eq bool true false, @eq ad node1 node2 *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) false *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  rewrite H14.  rewrite (Neqb_correct (high (bs, (share, counter)) node2)).  intro H15.
(* Goal: config_node_OK cfg node *)
  discriminate H15.  apply low_high_neq.  assumption.  assumption.  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro H14.  elim H10; intro.  elim H12; intro.  rewrite H15; rewrite H16; reflexivity.
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  elim H16; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H15; rewrite H17.  apply bool_fun_neq_zero_one.  assumption.  assumption.  
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H15.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_zero.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  assumption.  elim H15; intro.  elim H12; intro.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H16; rewrite H17.  apply bool_fun_neq_one_zero.  assumption.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim H17; intro.  rewrite H16; rewrite H18; reflexivity.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H16.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_one.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  assumption.  elim H12; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H17.  apply bool_fun_neq_internal_zero.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  elim H17; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node2))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node2))).
(* Goal: config_node_OK cfg node *)
  rewrite H18.  apply bool_fun_neq_internal_one.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply
   H00
    with
      (m := max
              (nat_of_N
                 (var (bs, (share, counter))
                    (low (bs, (share, counter)) node2)))
              (nat_of_N
                 (var (bs, (share, counter))
                    (high (bs, (share, counter)) node2)))).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H0.  apply lt_max_2.  apply BDDcompare_lt.  apply BDDvar_ordered_low.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply in_dom_is_internal; assumption.  apply BDDcompare_lt.
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_high.  assumption.  apply in_dom_is_internal; assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  reflexivity.  assumption.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node2) false)
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node2) true)).
(* Goal: forall _ : bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1), bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H14.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node2)
                (var (bs, (share, counter)) node2) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDlow.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node2)
                (var (bs, (share, counter)) node2) true).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_eq_symm.  apply bool_fun_of_BDDhigh.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node2) false)
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node2) true)).
(* Goal: forall _ : bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1), bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H14.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node1)
                (var (bs, (share, counter)) node2) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  apply bool_fun_eq_symm.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node1)
                (var (bs, (share, counter)) node2) true).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_restrict_eq.  assumption.  cut
   (bool_fun_independent (bool_fun_of_BDD (bs, (share, counter)) node1)
      (var (bs, (share, counter)) node2)).
(* Goal: bool_fun_eq bf1 bf2 *)
  intro H14.  unfold bool_fun_independent in H14.  unfold bool_fun_eq in |- *.  unfold bool_fun_restrict in |- *.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eval at 1 3 in |- *.  intro vb.  rewrite (H14 vb); reflexivity.  apply
   BDDvar_independent_1
    with (n := nat_of_N (var (bs, (share, counter)) node1)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  reflexivity.  assumption.  apply low_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply low_OK.  assumption.  assumption.  apply high_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply high_OK.  assumption.  assumption.  cut
   (BDDcompare (var (bs, (share, counter)) node2)
      (var (bs, (share, counter)) node1) = Datatypes.Lt).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  clear y; intro y.  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node1)).
  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node2)).
  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node1)).
  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node2)).
(* Goal: forall (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)), @eq ad node1 node2 *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intros H10 H11 H12 H13.  cut (low (bs, (share, counter)) node1 = high (bs, (share, counter)) node1).
(* Goal: forall _ : @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1), @eq ad node1 node2 *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intros H14.  cut
   (Neqb (low (bs, (share, counter)) node1)
      (high (bs, (share, counter)) node1) = false).
(* Goal: forall _ : @eq bool true false, @eq ad node1 node2 *)
(* Goal: @eq bool (N.eqb (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) false *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  rewrite H14.  rewrite (Neqb_correct (high (bs, (share, counter)) node1)).  intro H15.
(* Goal: config_node_OK cfg node *)
  discriminate H15.  apply low_high_neq.  assumption.  assumption.  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro H14.  elim H11; intro.  elim H13; intro.  rewrite H15; rewrite H16; reflexivity.
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  elim H16; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H15; rewrite H17.  apply bool_fun_neq_zero_one.  assumption.  assumption.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H15.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_zero.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  assumption.  elim H15; intro.  elim H13; intro.
  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H16; rewrite H17.  apply bool_fun_neq_one_zero.  assumption.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  elim H17; intro.  rewrite H16; rewrite H18; reflexivity.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H16.  apply bool_fun_neq_lemma.  apply bool_fun_neq_internal_one.  assumption.
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal.  assumption.  assumption.  elim H13; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H17.  apply bool_fun_neq_internal_zero.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  elim H17; intro.  absurd
   (bool_fun_eq
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node1))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node1))).
(* Goal: config_node_OK cfg node *)
  rewrite H18.  apply bool_fun_neq_internal_one.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply
   H00
    with
      (m := max
              (nat_of_N
                 (var (bs, (share, counter))
                    (low (bs, (share, counter)) node1)))
              (nat_of_N
                 (var (bs, (share, counter))
                    (high (bs, (share, counter)) node1)))).
(* Goal: lt (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq nat (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H0.  apply lt_max_12.  apply BDDcompare_lt.  apply BDDvar_ordered_low.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply in_dom_is_internal; assumption.  apply BDDcompare_lt.
(* Goal: config_node_OK cfg node *)
  apply BDDvar_ordered_high.  assumption.  apply in_dom_is_internal; assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  apply in_dom_is_internal; assumption.  reflexivity.  assumption.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node1) false)
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node1)
         (var (bs, (share, counter)) node1) true)).
(* Goal: forall _ : bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1), bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H14.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node1)
                (var (bs, (share, counter)) node1) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_of_BDDlow.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node1)
                (var (bs, (share, counter)) node1) true).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_eq_symm.  apply bool_fun_of_BDDhigh.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  cut
   (bool_fun_eq
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node1) false)
      (bool_fun_restrict (bool_fun_of_BDD (bs, (share, counter)) node2)
         (var (bs, (share, counter)) node1) true)).
(* Goal: forall _ : bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1), bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) true) *)
(* Goal: bool_fun_independent (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1) *)
(* Goal: @eq comparison (BDDcompare (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1)) Lt *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node2 *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node1 *)
  intro H14.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node2)
                (var (bs, (share, counter)) node1) false).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_restrict_eq.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_restrict
                (bool_fun_of_BDD (bs, (share, counter)) node2)
                (var (bs, (share, counter)) node1) true).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_restrict_eq.  apply bool_fun_eq_symm.  assumption.
  cut
   (bool_fun_independent (bool_fun_of_BDD (bs, (share, counter)) node2)
      (var (bs, (share, counter)) node1)).
(* Goal: bool_fun_eq bf1 bf2 *)
  intro H14.  unfold bool_fun_independent in H14.  unfold bool_fun_eq in |- *.  unfold bool_fun_restrict in |- *.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eval at 1 3 in |- *.  intro vb.  rewrite (H14 vb); reflexivity.  apply
   BDDvar_independent_1
    with (n := nat_of_N (var (bs, (share, counter)) node2)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  reflexivity.  assumption.  apply low_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply low_OK.  assumption.  assumption.  apply high_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply high_OK.  assumption.  assumption.  apply BDDcompare_sup_inf.
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  apply in_dom_is_internal.
(* Goal: config_node_OK cfg node *)
  assumption.
Qed.

Lemma BDDunique :
 forall cfg : BDDconfig,
 BDDconfig_OK cfg ->
 forall node1 node2 : ad,
 config_node_OK cfg node1 ->
 config_node_OK cfg node2 ->
 bool_fun_eq (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2) ->
 node1 = node2.
Proof.
(* Goal: forall (cfg : BDDconfig) (_ : BDDconfig_OK cfg) (node1 node2 : ad) (_ : config_node_OK cfg node1) (_ : config_node_OK cfg node2) (_ : bool_fun_eq (bool_fun_of_BDD cfg node1) (bool_fun_of_BDD cfg node2)), @eq ad node1 node2 *)
  intros cfg H node1 node2 H0 H1 H2.  apply
   BDDunique_1
    with
      (cfg := cfg)
      (n := max (nat_of_N (var cfg node1)) (nat_of_N (var cfg node2))).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  reflexivity.  assumption.  assumption.  assumption.
Qed.

Lemma bool_fun_eq_lemma :
 forall (bf1 bf2 : bool_fun) (x : BDDvar),
 bool_fun_ext bf1 ->
 bool_fun_ext bf2 ->
 bool_fun_eq (bool_fun_restrict bf1 x true) (bool_fun_restrict bf2 x true) ->
 bool_fun_eq (bool_fun_restrict bf1 x false) (bool_fun_restrict bf2 x false) ->
 bool_fun_eq bf1 bf2.
Proof.
(* Goal: bool_fun_eq bf1 bf2 *)
  intros bf1 bf2 x H H0 H1 H2.  unfold bool_fun_eq in |- *.  intro vb.  elim (sumbool_of_bool (vb x)); intro.
(* Goal: @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
  cut (var_binding_eq (augment vb x true) vb).  intro H3.  cut (bool_fun_eval bf2 (augment vb x true) = bool_fun_eval bf2 vb).
(* Goal: forall (_ : @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb)) (_ : @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb)), @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  cut (bool_fun_eval bf1 (augment vb x true) = bool_fun_eval bf1 vb).  intros H4 H5.
(* Goal: @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  rewrite <- H4.  rewrite <- H5.  unfold bool_fun_eq, bool_fun_restrict in H1.
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  unfold bool_fun_eval at 1 3 in H1.  apply H1.  apply H.  assumption.  apply H0.
(* Goal: var_binding_eq (augment vb x false) vb *)
  assumption.  apply augment_eq.  assumption.  cut (var_binding_eq (augment vb x false) vb).
(* Goal: forall _ : var_binding_eq (augment vb x false) vb, @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  intro H3.  cut (bool_fun_eval bf2 (augment vb x false) = bool_fun_eval bf2 vb).
(* Goal: forall (_ : @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb)) (_ : @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb)), @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  cut (bool_fun_eval bf1 (augment vb x false) = bool_fun_eval bf1 vb).  intros H4 H5.
(* Goal: @eq bool (bool_fun_eval bf1 vb) (bool_fun_eval bf2 vb) *)
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  rewrite <- H4.  rewrite <- H5.  unfold bool_fun_eq, bool_fun_restrict in H2.
(* Goal: @eq bool (bool_fun_eval bf1 (augment vb x false)) (bool_fun_eval bf1 vb) *)
(* Goal: @eq bool (bool_fun_eval bf2 (augment vb x false)) (bool_fun_eval bf2 vb) *)
(* Goal: var_binding_eq (augment vb x false) vb *)
  unfold bool_fun_eval at 1 3 in H2.  apply H2.  apply H.  assumption.  apply H0.
(* Goal: var_binding_eq (augment vb x false) vb *)
  assumption.  apply augment_eq.  assumption.  
Qed.
  
Lemma bool_fun_preservation_1 :
 forall cfg cfg' : BDDconfig,
 BDDconfig_OK cfg ->
 BDDconfig_OK cfg' ->
 (forall (x : BDDvar) (l r a : ad),
  MapGet _ (fst cfg) a = Some (x, (l, r)) ->
  MapGet _ (fst cfg') a = Some (x, (l, r))) ->
 forall (n : nat) (node : ad),
 n = nat_of_N (var cfg node) ->
 config_node_OK cfg node ->
 bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node).
Proof.
(* Goal: forall (cfg cfg' : BDDconfig) (_ : BDDconfig_OK cfg) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var cfg node))) (_ : config_node_OK cfg node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node) *)
  intro cfg.  elim cfg; clear cfg; intros bs y.  elim y; clear y; intros share counter.
(* Goal: forall (cfg' : BDDconfig) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : BDDconfig_OK cfg') (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) cfg') a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intro cfg'.  elim cfg'; clear cfg'; intros bs' y'.  elim y'; clear y'; intros share' counter'.
(* Goal: forall (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter'))) (_ : forall (x : BDDvar) (l r a : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter'))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (n : nat) (node : ad) (_ : @eq nat n (N.to_nat (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node))) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
  intros H H0 H1 n.  apply
   lt_wf_ind
    with
      (P := fun n : nat =>
            forall node : ad,
            n = nat_of_N (var (bs, (share, counter)) node) ->
            config_node_OK (bs, (share, counter)) node ->
            bool_fun_eq (bool_fun_of_BDD (bs', (share', counter')) node)
              (bool_fun_of_BDD (bs, (share, counter)) node)).
(* Goal: forall _ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node, bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intros n0 H2 node H3 H4.  cut (config_node_OK (bs', (share', counter')) node).  intro H5.  elim H4; intro.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite H6.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) bool_fun_zero *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite (proj1 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  elim H6; intro.  rewrite H7.  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)))
   .
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  cut (is_internal_node (bs, (share, counter)) node).
(* Goal: forall (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (_ : is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  cut (is_internal_node (bs', (share', counter')) node).  intros H8 H9.  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs', (share', counter'))
         (low (bs', (share', counter')) node))
      (bool_fun_of_BDD (bs, (share, counter))
         (low (bs, (share, counter)) node))).
  cut
   (bool_fun_eq
      (bool_fun_of_BDD (bs', (share', counter'))
         (high (bs', (share', counter')) node))
      (bool_fun_of_BDD (bs, (share, counter))
         (high (bs, (share, counter)) node))).
(* Goal: forall (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (_ : config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intros H10 H11.  cut (var (bs, (share, counter)) node = var (bs', (share', counter')) node).
(* Goal: bool_fun_ext (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: @eq BDDvar (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intro H12.  apply bool_fun_eq_lemma with (x := var (bs, (share, counter)) node).  apply bool_fun_of_BDD_ext.
(* Goal: bool_fun_ext (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) true) *)
(* Goal: bool_fun_eq (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) (bool_fun_restrict (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) false) *)
(* Goal: @eq BDDvar (var (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (var (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  apply bool_fun_of_BDD_ext.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs', (share', counter'))
                (high (bs', (share', counter')) node)).
(* Goal: config_node_OK cfg node *)
  apply bool_fun_eq_symm.  rewrite H12.  apply bool_fun_of_BDDhigh.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs, (share, counter))
                (high (bs, (share, counter)) node)).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_of_BDDhigh.  assumption.  assumption.  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs', (share', counter'))
                (low (bs', (share', counter')) node)).
(* Goal: config_node_OK cfg node *)
  rewrite H12.  apply bool_fun_eq_symm; apply bool_fun_of_BDDlow; assumption; assumption.
  apply
   bool_fun_eq_trans
    with
      (bf2 := bool_fun_of_BDD (bs, (share, counter))
                (low (bs, (share, counter)) node)).
(* Goal: config_node_OK cfg node *)
  assumption.  apply bool_fun_of_BDDlow; assumption; assumption.  unfold var in |- *.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  inversion H9.  inversion H12.  inversion H13.  rewrite H14.  rewrite (H1 x x0 x1 node H14).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  cut
   (config_node_OK (bs, (share, counter)) (high (bs, (share, counter)) node)).  cut
   (config_node_OK (bs', (share', counter'))
      (high (bs', (share', counter')) node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (high (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (high (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intros H10 H11.  inversion H9.  inversion H12.  inversion H13.  cut
   (high (bs', (share', counter')) node = high (bs, (share, counter)) node).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  cut (low (bs', (share', counter')) node = low (bs, (share, counter)) node).  intros H15 H16.
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  elim H11; intro.  rewrite H16; rewrite H17.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) bool_fun_zero *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite (proj1 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  elim H17; intro.  rewrite H16; rewrite H18.
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)))
   .
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  rewrite H16.  apply
   H2
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (high (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H3.  apply BDDcompare_lt.  apply BDDvar_ordered_high.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  reflexivity.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold low in |- *.  rewrite H14.  rewrite (H1 x x0 x1 node H14).  reflexivity.  unfold high in |- *.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite H14.  rewrite (H1 x x0 x1 node H14).  reflexivity.  apply high_OK.  assumption.
(* Goal: config_node_OK cfg node *)
  assumption.  apply high_OK.  assumption.  assumption.  cut (low (bs', (share', counter')) node = low (bs, (share, counter)) node).
(* Goal: forall _ : @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intro H10.  rewrite H10.  cut
   (config_node_OK (bs, (share, counter)) (low (bs, (share, counter)) node)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) BDDzero) *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  intro H11.  elim H11.  intro H12.  rewrite H12.  rewrite (proj1 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)).
(* Goal: bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) BDDzero) bool_fun_zero *)
(* Goal: forall _ : or (@eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)))) true), bool_fun_eq (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) (bool_fun_of_BDD (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node)) *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: @eq ad (low (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node) (low (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node) *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  rewrite (proj1 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  intro H12.  elim H12; intro.  rewrite H13.
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs, (share, counter)) H)))
   .
  rewrite
   (proj1 (proj2 (bool_fun_of_BDD_semantics (bs', (share', counter')) H0)))
   .
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  unfold bool_fun_eq in |- *; reflexivity.  apply
   H2
    with
      (m := nat_of_N
              (var (bs, (share, counter)) (low (bs, (share, counter)) node))).
(* Goal: config_node_OK cfg node *)
  rewrite H3.  apply BDDcompare_lt.  apply BDDvar_ordered_low.  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  apply in_dom_is_internal.  assumption.  reflexivity.  apply low_OK.
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  apply low_OK.  assumption.  assumption.  unfold low in |- *.
(* Goal: @eq ad match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter'))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end match MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node with | Some (pair x (pair l r as p0) as p) => l | None => N0 end *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
(* Goal: is_internal_node (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) node *)
(* Goal: config_node_OK (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')) node *)
  inversion H9.  inversion H10.  inversion H11.  rewrite H12.  rewrite (H1 x x0 x1 node H12).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  reflexivity.  apply in_dom_is_internal.  elim (option_sum _ (MapGet _ (fst (bs, (share, counter))) node)).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  intro y.  elim y; intro x.  elim x; intros x0 x1.  elim x1; intros y0 y1 y2.  unfold in_dom in |- *.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite (H1 x0 y0 y1 node y2).  reflexivity.  intro y.  unfold in_dom in H7.
(* Goal: config_node_OK cfg node *)
  rewrite y in H7; discriminate.  apply in_dom_is_internal.  assumption.  elim H4; intro.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  rewrite H5.  left; reflexivity.  elim H5; intro.  rewrite H6; right; left; reflexivity.
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  right; right.  elim (option_sum _ (MapGet _ (fst (bs, (share, counter))) node)).
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  intro y.  elim y; intro x.  elim x; intro y0.  intro y1.  elim y1; intros y2 y3 y4.  unfold in_dom in |- *; rewrite (H1 y0 y2 y3 node y4); reflexivity.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) node) (@None (prod BDDvar (prod ad ad))), @eq bool (in_dom (prod BDDvar (prod ad ad)) node (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs' (@pair BDDsharing_map ad share' counter')))) true *)
  intro y.  unfold in_dom in H6; rewrite y in H6; discriminate.
Qed.

Lemma bool_fun_preservation :
 forall (cfg cfg' : BDDconfig) (node : ad),
 BDDconfig_OK cfg ->
 BDDconfig_OK cfg' ->
 (forall (x : BDDvar) (l r a : ad),
  MapGet _ (fst cfg) a = Some (x, (l, r)) ->
  MapGet _ (fst cfg') a = Some (x, (l, r))) ->
 config_node_OK cfg node ->
 bool_fun_eq (bool_fun_of_BDD cfg' node) (bool_fun_of_BDD cfg node).
Proof.
(* Goal: config_node_OK cfg node *)
  intros cfg cfg' node H H0 H1 H2.  apply bool_fun_preservation_1 with (n := nat_of_N (var cfg node)).  assumption.
(* Goal: @eq nat (N.to_nat (var cfg node)) (N.to_nat (var cfg node)) *)
(* Goal: config_node_OK cfg node *)
  assumption.  assumption.  reflexivity.  assumption.
Qed.