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

  Definition BDDstate := Map (BDDvar * (ad * ad)).
	(* BDDstates are maps from (node) addresses to actual nodes.
	These nodes contain a variable, the address of the left subBDD,
	and the address of the right subBDD.
	BDDstates should obey a few invariants: *)

  Definition initBDDstate := newMap (BDDvar * (ad * ad)).

  Inductive BDDbounded (bs : BDDstate) : ad -> BDDvar -> Prop :=
    | BDDbounded_0 : forall n : BDDvar, BDDbounded bs BDDzero n
    | BDDbounded_1 : forall n : BDDvar, BDDbounded bs BDDone n
    | BDDbounded_2 :
        forall (node : ad) (n x : BDDvar) (l r : ad),
        MapGet _ bs node = Some (x, (l, r)) ->
        BDDcompare x n = Datatypes.Lt ->
        Neqb l r = false ->
        BDDbounded bs l x -> BDDbounded bs r x -> BDDbounded bs node n.

  Lemma BDDbounded_lemma :
   forall (bs : BDDstate) (node : ad) (n : BDDvar),
   BDDbounded bs node n ->
   node = BDDzero \/
   node = BDDone \/
   (exists x : BDDvar,
      (exists l : BDDvar,
         (exists r : BDDvar,
            MapGet _ bs node = Some (x, (l, r)) /\
            BDDcompare x n = Datatypes.Lt /\
            Neqb l r = false /\ BDDbounded bs l x /\ BDDbounded bs r x))).
  Proof.
(* Goal: forall (a : BDDstate) (b : prod BDDsharing_map ad) (l r : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) a b)) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) l) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) r) (_ : forall (x' : BDDvar) (l' r' a0 : 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) a b)) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), BDDsharing_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r))) (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r)))) *)
    intro bs.  intro node.  intro n.  intro H.  elim H.  intros n0.  left.  trivial.  intros n0.
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    right.  left.  trivial.  intros node0 n0 x l r H0 H1 H2 H3 H4 H5 H6.  right.  right.  split with x.
(* Goal: @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 node0) (@Some (prod BDDvar (prod BDDvar BDDvar)) (@pair BDDvar (prod BDDvar BDDvar) x (@pair BDDvar BDDvar l r)))) (and (@eq comparison (BDDcompare x n0) Lt) (and (@eq bool (N.eqb l r) false) (and (BDDbounded bs l x) (BDDbounded bs r x)))))) *)
    split with l.  split with r.  split.  assumption.  split.  assumption.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    split.  assumption.  split.  assumption.  assumption.
  Qed.

  Lemma increase_bound :
   forall (bs : BDDstate) (n n' : BDDvar) (node : ad),
   BDDbounded bs node n ->
   BDDcompare n n' = Datatypes.Lt -> BDDbounded bs node n'.
  Proof.
(* Goal: forall (a : BDDstate) (b : prod BDDsharing_map ad) (l r : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) a b)) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) l) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) r) (_ : forall (x' : BDDvar) (l' r' a0 : 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) a b)) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), BDDsharing_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r))) (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r)))) *)
    intro bs.  intro n.  intro n'.  intro node.  intro H.  elim H.  intros n0 H0.
(* Goal: forall (n : BDDvar) (_ : @eq comparison (BDDcompare n n') Lt), BDDbounded bs BDDone n' *)
(* Goal: forall (node : ad) (n x : BDDvar) (l r : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs node) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (_ : @eq comparison (BDDcompare x n) Lt) (_ : @eq bool (N.eqb l r) false) (_ : BDDbounded bs l x) (_ : forall _ : @eq comparison (BDDcompare x n') Lt, BDDbounded bs l n') (_ : BDDbounded bs r x) (_ : forall _ : @eq comparison (BDDcompare x n') Lt, BDDbounded bs r n') (_ : @eq comparison (BDDcompare n n') Lt), BDDbounded bs node n' *)
    apply BDDbounded_0.  intros n0 H0.  apply BDDbounded_1. intros node0 n0 x l r H0 H1 H2 H3 H4 H5 H6 H7.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDbounded_2 with (x := x) (l := l) (r := r).  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDcompare_trans with (y := n0).  assumption.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption. assumption. assumption.
  Qed.

  Lemma boundedness_preservation :
   forall bs bs' : BDDstate,
   (forall (a l r : ad) (x : BDDvar),
    MapGet _ bs a = Some (x, (l, r)) -> MapGet _ bs' a = Some (x, (l, r))) ->
   forall (n : BDDvar) (node : ad),
   BDDbounded bs node n -> BDDbounded bs' node n.
  Proof.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l BDDzero))) BDDzero x *)
(* Goal: forall _ : or (@eq ad r BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) r y) true), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros bs bs' H n node H0. elim H0. intro n0. apply BDDbounded_0. intro n0.  apply BDDbounded_1.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S x) *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros node0 n0 x l r H1 H2 H3 H4 H5 H6 H7.  apply BDDbounded_2 with (x := x) (l := l) (r := r).  apply H.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  assumption.  assumption.  assumption.  assumption.
  Qed.

  Definition BDDordered (bs : BDDstate) (node : ad) :=
    match MapGet _ bs node with
    | None => True
    | Some (n, _) => BDDbounded bs node (ad_S n)
    end.

  Definition BDD_OK (bs : BDDstate) (node : ad) := BDDordered bs node.

  Definition BDDstate_OK (bs : BDDstate) :=
    MapGet _ bs BDDzero = None /\
    MapGet _ bs BDDone = None /\
    (forall a : ad, in_dom _ a bs = true -> BDD_OK bs a).

  Lemma initBDDstate_OK : BDDstate_OK initBDDstate.
  Proof.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDstate_OK, initBDDstate in |- *. split. simpl in |- *. trivial. split. simpl in |- *.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    trivial.  intros a H. compute in H.  discriminate H.
  Qed.

  Definition BDDsharing_map := Map (Map (Map ad)).
	(* These are maps from left-hand sides l to
	maps from right-hand sides r to
	maps from BDD variables x to
	the address of the unique node in the given BDDstate
	that contains (x, (l, r)). *)

  Definition initBDDsharing_map := newMap (Map (Map ad)).

  Definition BDDshare_lookup (share : BDDsharing_map) 
    (x : BDDvar) (l r : ad) : option ad :=
    match MapGet _ share l with
    | None => None
    | Some m1 =>
        match MapGet _ m1 r with
        | None => None
        | Some m2 =>
            match MapGet _ m2 x with
            | None => None
            | Some y => Some y
            end
        end
    end.

  Definition BDDshare_put (share : BDDsharing_map) 
    (x : BDDvar) (l r counter : ad) : BDDsharing_map :=
    let m1 :=
      match MapGet _ share l with
      | Some y => y
      | None => newMap (Map ad)
      end in
    let m2 :=
      match MapGet _ m1 r with
      | Some y => y
      | None => newMap ad
      end in
    let m2' := MapPut _ m2 x counter in
    let m1' := MapPut _ m1 r m2' in MapPut _ share l m1'.

  Lemma BDDshare_put_puts :
   forall (share : BDDsharing_map) (x : BDDvar) (l r counter : ad),
   BDDshare_lookup (BDDshare_put share x l r counter) x l r = Some counter.
  Proof.
(* Goal: forall (share : BDDsharing_map) (x : BDDvar) (l r counter : ad), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x l r) (@Some ad counter) *)
    intros share x l r counter.  unfold BDDshare_put in |- *.
(* Goal: @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim (option_sum _ (MapGet (Map (Map ad)) share l)).  intro y.  elim y.
(* Goal: forall (x0 : ad) (_ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad x0)), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    clear y.  intros x0 y.  rewrite y.  elim (option_sum _ (MapGet (Map ad) x0 r)).
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    intros y0.  elim y0.  clear y0.  intros x1 y0.  rewrite y0.  unfold BDDshare_lookup in |- *.
    rewrite
     (MapPut_semantics _ share l
        (MapPut (Map ad) x0 r (MapPut ad x1 x counter)) l)
     .
(* Goal: @eq (option ad) match (if N.eqb l l then @Some (Map (Map ad)) (MapPut (Map ad) x0 r (MapPut ad x1 x counter)) else MapGet (Map (Map ad)) share l) with | Some m1 => match MapGet (Map ad) m1 r with | Some m2 => match MapGet ad m2 x with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    cut (Neqb l l = true).  intros H.  rewrite H.
(* Goal: @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad x1 x counter)) r with | Some m2 => match MapGet ad m2 x with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter) *)
(* Goal: @eq bool (N.eqb l l) true *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    rewrite (MapPut_semantics _ x0 r (MapPut ad x1 x counter) r).
(* Goal: @eq (option ad) match (if N.eqb r r then @Some (Map ad) (MapPut ad x1 x counter) else MapGet (Map ad) x0 r) with | Some m2 => match MapGet ad m2 x with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter) *)
(* Goal: @eq bool (N.eqb l l) true *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    cut (Neqb r r = true).  intros H0.  rewrite H0.
(* Goal: @eq (option ad) match MapGet ad (MapPut ad x1 x counter) x with | Some y => @Some ad y | None => @None ad end (@Some ad counter) *)
(* Goal: @eq bool (N.eqb r r) true *)
(* Goal: @eq bool (N.eqb l l) true *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    rewrite (MapPut_semantics _ x1 x counter x).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb x x = true).  intros H1.  rewrite H1.  trivial.
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    apply Neqb_correct.  apply Neqb_correct.  apply Neqb_correct.  intros y0.
(* Goal: @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option ad) (MapGet ad x1 x') (@None ad), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@None (Map ad)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite y0.  unfold BDDshare_lookup in |- *.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad) x0 r (MapPut ad (newMap ad) x counter)) l)
     .
(* Goal: @eq (option ad) match (if N.eqb l l then @Some (Map (Map ad)) (M1 (Map ad) r (M1 ad x counter)) else MapGet (Map (Map ad)) share l) with | Some m1 => match MapGet (Map ad) m1 r with | Some m2 => match MapGet ad m2 x with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter) *)
    rewrite (Neqb_correct l).
    rewrite
     (MapPut_semantics (Map ad) x0 r (MapPut ad (newMap ad) x counter) r)
     .
(* Goal: @eq (option ad) match (if N.eqb r r then @Some (Map ad) (M1 ad x counter) else @None (Map ad)) with | Some m2 => match MapGet ad m2 x with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter) *)
    rewrite (Neqb_correct r).
(* Goal: @eq (option ad) match MapGet ad (MapPut ad (newMap ad) x counter) x with | Some y => @Some ad y | None => @None ad end (@Some ad counter) *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x l r) (@Some ad counter) *)
    rewrite (MapPut_semantics ad (newMap ad) x counter x).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite (Neqb_correct x).  trivial.  intros y.  rewrite y.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDshare_lookup in |- *.  simpl in |- *.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (M1 (Map ad) r (M1 ad x counter)) l).
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite (Neqb_correct l).  simpl in |- *.  rewrite (Neqb_correct r).  simpl in |- *.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite (Neqb_correct x).  trivial.
  Qed.

  Lemma BDDshare_put_no_new_node :
   forall (share : BDDsharing_map) (x x' : BDDvar)
     (l l' r r' counter counter' : ad),
   BDDshare_lookup (BDDshare_put share x l r counter) x' l' r' =
   Some counter' ->
   BDDshare_lookup share x' l' r' = Some counter' \/
   (x, (l, r)) = (x', (l', r')).
  Proof.
(* Goal: @eq (option ad) match MapGet (Map (Map ad)) (BDDshare_put share x l r counter) l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intros share x x' l l' r r' counter counter'.  unfold BDDshare_put in |- *.
(* Goal: @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim (option_sum _ (MapGet (Map (Map ad)) share l)).  intro y.  elim y.
(* Goal: forall (x0 : ad) (_ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad x0)), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    clear y.  intros x0 y H.  rewrite y in H.
(* Goal: or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    elim (option_sum _ (MapGet (Map ad) x0 r)).  intro y0.  elim y0.  clear y0.
(* Goal: forall (x1 : Map ad) (_ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@Some (Map ad) x1)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@None (Map ad)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intros x1 y0.  rewrite y0 in H.  unfold BDDshare_lookup in |- *.
(* Goal: @eq (option ad) match MapGet (Map (Map ad)) (BDDshare_put share x l r counter) l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    unfold BDDshare_lookup in H.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad) x0 r (MapPut ad x1 x counter)) l')
      in H.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    cut (Neqb l l' = true \/ Neqb l l' = false).  intro H0.  elim H0.  clear H0.
(* Goal: forall _ : @eq bool (N.eqb y1 BDDone) true, False *)
    intro H0.  rewrite H0 in H.
(* Goal: or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    rewrite (MapPut_semantics (Map ad) x0 r (MapPut ad x1 x counter) r') in H.
(* Goal: forall _ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb r r' = true \/ Neqb r r' = false).  intro H1.  elim H1.  clear H1.
(* Goal: forall _ : @eq bool (N.eqb y1 a0) false, @eq (option (prod BDDvar (prod ad ad))) (if N.eqb y1 a0 then @Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) else MapGet (prod BDDvar (prod ad ad)) y a0) (@None (prod BDDvar (prod ad ad))) *)
(* Goal: @eq bool (N.eqb y1 a0) false *)
(* Goal: @eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad y0 y1)) x l r))))) true *)
    intro H1.  rewrite H1 in H.
(* Goal: or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r) (@None (Map ad)), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    rewrite (MapPut_semantics ad x1 x counter x') in H.
(* Goal: forall (_ : or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false)) (_ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false)), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb x x' = true \/ Neqb x x' = false).  intro H2.  elim H2.  clear H2.
(* Goal: or (@eq ad x0 BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) x0 bs) true) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H2.  rewrite H2 in H.  right.  cut (x = x').  cut (l = l').  cut (r = r').  intros H3 H4 H5.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H3.  rewrite H4.  rewrite H5.  trivial.  apply Neqb_complete.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  apply Neqb_complete.  assumption.  apply Neqb_complete.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro H3.  rewrite H3 in H.  cut (l = l').  intro H4.  cut (r = r').
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    intro H5.  rewrite <- H4.  rewrite <- H5.  rewrite y.  rewrite y0.  left.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  apply Neqb_complete.  assumption.  apply Neqb_complete.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  elim (Neqb x x').  auto.  auto.  intro H2.  rewrite H2 in H.
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    cut (l = l').  intro H3.  rewrite <- H3.  rewrite y.  left.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply Neqb_complete.  assumption.  elim (Neqb r r').  auto.  auto.
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    intro H1.  rewrite H1 in H.  left.  assumption.  elim (Neqb l l').  auto.  
(* Goal: @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    auto.  intro y0.  unfold BDDshare_lookup in |- *.  unfold BDDshare_lookup in H.
(* Goal: @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite y0 in H.  cut (Neqb l l' = true \/ Neqb l l' = false).  intro H0.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim H0.  clear H0.  intro H0.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad) x0 r (MapPut ad (newMap ad) x counter)) l')
      in H.
(* Goal: or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    rewrite H0 in H.
    rewrite
     (MapPut_semantics (Map ad) x0 r (MapPut ad (newMap ad) x counter) r')
      in H.
(* Goal: forall _ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb r r' = true \/ Neqb r r' = false).  intro H1.  elim H1.  clear H1.
(* Goal: forall _ : @eq bool (N.eqb r r') true, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    intros H1.  rewrite H1 in H.  cut (l = l').  cut (r = r').  intros H2 H3.  rewrite <- H2.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a), False *)
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite <- H3.  rewrite y.  rewrite y0.
(* Goal: forall (_ : or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false)) (_ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false)), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb x x' = true \/ Neqb x x' = false).  intro H4.  elim H4.  clear H4.
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intro H4.  cut (x = x').  intro H5.  rewrite <- H5.  auto.  apply Neqb_complete.
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    assumption.  intro H5.  left.
(* Goal: @eq (option ad) (@None ad) (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: @eq ad r r' *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq (option ad) match MapGet (Map (Map ad)) share l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
(* Goal: forall (_ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad)))) (_ : @eq (option ad) (BDDshare_lookup (MapPut (Map (Map ad)) share l (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter))) x' l' r') (@Some ad counter')), or (@eq (option ad) (BDDshare_lookup share x' l' r') (@Some ad counter')) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
    rewrite (MapPut_semantics ad (newMap ad) x counter x') in H.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H5 in H.  simpl in H.  assumption.  elim (Neqb x x').  auto.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    auto.  apply Neqb_complete.  assumption.  apply Neqb_complete.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro H2.  rewrite H2 in H.  cut (l = l').  intro H3.  rewrite <- H3.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite y.  auto.  apply Neqb_complete.  assumption.  elim (Neqb r r').
(* Goal: forall _ : @eq bool (N.eqb y1 a0) false, @eq (option (prod BDDvar (prod ad ad))) (if N.eqb y1 a0 then @Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) else MapGet (prod BDDvar (prod ad ad)) y a0) (@None (prod BDDvar (prod ad ad))) *)
(* Goal: @eq bool (N.eqb y1 a0) false *)
(* Goal: @eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad y0 y1)) x l r))))) true *)
    auto.  auto.  intro H1.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad) x0 r (MapPut ad (newMap ad) x counter)) l')
      in H.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H1 in H.  auto.  elim (Neqb l l').  auto.  auto.  intro y.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a), False *)
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDshare_lookup in |- *.  rewrite y.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad) (newMap (Map ad)) r
           (MapPut ad
              match MapGet (Map ad) (newMap (Map ad)) r with
              | None => newMap ad
              | Some y => y
              end x counter)) l').
(* Goal: @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
    cut (Neqb l l' = true \/ Neqb l l' = false).
(* Goal: forall (_ : or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false)) (_ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false)), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb x x' = true \/ Neqb x x' = false).
(* Goal: forall _ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb r r' = true \/ Neqb r r' = false).
(* Goal: forall _ : @eq bool (N.eqb y1 a0) false, @eq (option (prod BDDvar (prod ad ad))) (if N.eqb y1 a0 then @Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) else MapGet (prod BDDvar (prod ad ad)) y a0) (@None (prod BDDvar (prod ad ad))) *)
(* Goal: @eq bool (N.eqb y1 a0) false *)
(* Goal: @eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad y0 y1)) x l r))))) true *)
    intros H H0 H1 H2.  elim H1.  clear H1.  intro H1.  rewrite H1 in H2.
    rewrite
     (MapPut_semantics (Map ad) (newMap (Map ad)) r
        (MapPut ad
           match MapGet (Map ad) (newMap (Map ad)) r with
           | None => newMap ad
           | Some y => y
           end x counter) r') in H2.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    elim H.  clear H.  intro H.  rewrite H in H2.  simpl in H2.  elim H0.
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intro H3.  cut (l = l').  cut (r = r').  cut (x = x').  intros H4 H5 H6.  rewrite <- H4.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite <- H5.  rewrite <- H6.  auto.  apply Neqb_complete.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply Neqb_complete.  assumption.  apply Neqb_complete.  assumption.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    intro H3.  rewrite H3 in H2.  discriminate H2.  intro H3.  rewrite H3 in H2.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    simpl in H2.  discriminate H2.  intro H3.  rewrite H3 in H2.  auto.
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim (Neqb r r').  auto.  auto.  elim (Neqb x x').  auto.  auto.
(* Goal: or (@eq bool false true) (@eq bool false false) *)
    elim (Neqb l l').  auto.  auto.
  Qed.

  Lemma BDDshare_put_preserves_nodes :
   forall (share : BDDsharing_map) (x x' : BDDvar)
     (l l' r r' counter counter' : ad),
   BDDshare_lookup share x' l' r' = Some counter' ->
   (x, (l, r)) <> (x', (l', r')) ->
   BDDshare_lookup (BDDshare_put share x l r counter) x' l' r' =
   Some counter'.
  Proof.
(* Goal: @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
    intros share x x' l l' r r' counter counter' H H0.  cut (Neqb l l' = true \/ Neqb l l' = false).
(* Goal: forall _ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb r r' = true \/ Neqb r r' = false).
(* Goal: forall (_ : or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false)) (_ : or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false)), @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    cut (Neqb x x' = true \/ Neqb x x' = false).  intros H1 H2 H3.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))), @eq bool match MapGet (prod BDDvar (prod ad ad)) bs x0 with | Some a => true | None => false end true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb x x' = false \/ Neqb l l' = false \/ Neqb r r' = false).  intro H4.
(* Goal: @eq (option ad) (BDDshare_lookup (BDDshare_put share x l r counter) x' l' r') (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    unfold BDDshare_lookup in |- *.  unfold BDDshare_lookup in H.
(* Goal: @eq (option ad) match MapGet (Map (Map ad)) (BDDshare_put share x l r counter) l' with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    unfold BDDshare_put in |- *.
    rewrite
     (MapPut_semantics (Map (Map ad)) share l
        (MapPut (Map ad)
           match MapGet (Map (Map ad)) share l with
           | None => newMap (Map ad)
           | Some y => y
           end r
           (MapPut ad
              match
                MapGet (Map ad)
                  match MapGet (Map (Map ad)) share l with
                  | None => newMap (Map ad)
                  | Some y => y
                  end r
              with
              | None => newMap ad
              | Some y => y
              end x counter)) l').
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: @eq BDDvar x x' *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim H3.  intro H5.  rewrite H5.  clear H3.  cut (l = l').  intro H3.
(* Goal: @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite <- H3 in H.  elim (option_sum _ (MapGet (Map (Map ad)) share l)).
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro y.  elim y.  clear y.  intros x0 y.  rewrite y.  rewrite y in H.  elim H2.
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: @eq BDDvar x x' *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intro H6.  cut (r = r').  intro H7.
    rewrite
     (MapPut_semantics (Map ad) x0 r
        (MapPut ad
           match MapGet (Map ad) x0 r with
           | None => newMap ad
           | Some y => y
           end x counter) r').
(* Goal: forall (x : BDDvar) (l r _ : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) y y0)), and (forall (a0 : ad) (_ : @eq bool (Nleb (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r)))) a0) true), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r))) a0) (@None (prod BDDvar (prod ad ad)))) (@eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r))))) true) *)
    rewrite H6.  elim (option_sum _ (MapGet (Map ad) x0 r')).  intro y0.  elim y0.
(* Goal: forall (a : BDDsharing_map) (b : ad) (x : BDDvar) (l r _ : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad a b))), and (forall (a1 : ad) (_ : @eq bool (Nleb (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad a b)) x l r)))) a1) true), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad a b)) x l r))) a1) (@None (prod BDDvar (prod ad ad)))) (@eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad a b)) x l r))))) true) *)
    clear y0.  intros x1 y0.  rewrite y0 in H. elim (option_sum _ (MapGet ad x1 x')).
(* Goal: forall _ : @sig ad (fun y : ad => @eq (option ad) (MapGet ad x1 x') (@Some ad y)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option ad) (MapGet ad x1 x') (@None ad), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@None (Map ad)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    intros y1.  elim y1.  clear y1.  intros x2 y1.  rewrite y1 in H.
(* Goal: @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option ad) (MapGet ad x1 x') (@None ad), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@None (Map ad)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite <- H7 in y0.  rewrite y0.  elim H1.  intros H8.  rewrite H3 in H0.
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite H7 in H0.  cut (x = x').  intro H9.  rewrite H9 in H0.  cut False.  tauto.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply H0.  reflexivity.  apply Neqb_complete.  assumption.  intros H8.
(* Goal: @eq (option ad) match MapGet ad (MapPut ad x1 x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option ad) (MapGet ad x1 x') (@None ad), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map ad)) (MapGet (Map ad) x0 r') (@None (Map ad)), @eq (option ad) match MapGet ad (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter) x' with | Some y => @Some ad y | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) x0 r (MapPut ad match MapGet (Map ad) x0 r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: forall _ : @eq (option (Map (Map ad))) (MapGet (Map (Map ad)) share l) (@None (Map (Map ad))), @eq (option ad) match MapGet (Map ad) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: @eq ad l l' *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, @eq (option ad) match (if N.eqb l l' then @Some (Map (Map ad)) (MapPut (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r (MapPut ad match MapGet (Map ad) match MapGet (Map (Map ad)) share l with | Some y => y | None => newMap (Map ad) end r with | Some y => y | None => newMap ad end x counter)) else MapGet (Map (Map ad)) share l') with | Some m1 => match MapGet (Map ad) m1 r' with | Some m2 => match MapGet ad m2 x' with | Some y => @Some ad y | None => @None ad end | None => @None ad end | None => @None ad end (@Some ad counter') *)
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    rewrite (MapPut_semantics ad x1 x counter x').  rewrite H8.  rewrite y1.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro y1.  rewrite y1 in H.  discriminate H.  intro y0.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite y0 in H.  discriminate H.  apply Neqb_complete.  assumption.
(* Goal: forall _ : forall (n : BDDvar) (node : ad) (_ : BDDbounded y node n), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) node n, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H6.
    rewrite
     (MapPut_semantics (Map ad) x0 r
        (MapPut ad
           match MapGet (Map ad) x0 r with
           | None => newMap ad
           | Some y => y
           end x counter) r').
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H6.  assumption.  intro y.  rewrite y in H.  discriminate H.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply Neqb_complete.  assumption.  intro H5.  rewrite H5.  assumption.  
(* Goal: @eq bool (Nleb (Npos (xO xH)) (ad_S y1)) true *)
    elim H1.  intro H4.  cut (x = x').  intro H5.  elim H2.  intro H6.  cut (r = r').  intro H7.
(* Goal: or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: forall _ : @eq bool (N.eqb l l') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: @eq ad r r' *)
(* Goal: forall _ : @eq bool (N.eqb r r') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: @eq BDDvar x x' *)
(* Goal: forall _ : @eq bool (N.eqb x x') false, or (@eq bool (N.eqb x x') false) (or (@eq bool (N.eqb l l') false) (@eq bool (N.eqb r r') false)) *)
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim H3.  intro H8.  cut (l = l').  intro H9.  rewrite H5 in H0.  rewrite H7 in H0.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H9 in H0.  cut False.  tauto.  apply H0.  trivial.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply Neqb_complete.  assumption.  auto.  apply Neqb_complete.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  auto.  apply Neqb_complete.  assumption.  auto.
(* Goal: or (@eq bool (N.eqb x x') true) (@eq bool (N.eqb x x') false) *)
(* Goal: or (@eq bool (N.eqb r r') true) (@eq bool (N.eqb r r') false) *)
(* Goal: or (@eq bool (N.eqb l l') true) (@eq bool (N.eqb l l') false) *)
    elim (Neqb x x').  auto.  auto.  elim (Neqb r r').  auto.  auto.
(* Goal: or (@eq bool false true) (@eq bool false false) *)
    elim (Neqb l l').  auto.  auto.
  Qed.

  Definition BDDsharing_OK (bs : BDDstate) (share : BDDsharing_map) :=
    forall (x : BDDvar) (l r a : ad),
    BDDshare_lookup share x l r = Some a <->
    MapGet _ bs a = Some (x, (l, r)).

  Lemma initBDDsharing_map_OK : BDDsharing_OK initBDDstate initBDDsharing_map.
  Proof.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDsharing_OK, initBDDstate, initBDDsharing_map in |- *. split. intros H.
(* Goal: @eq (option ad) (BDDshare_lookup (newMap (Map (Map ad))) x l r) (@Some ad a) *)
    compute in H. discriminate H. intros H. compute in H. discriminate H.
  Qed.

  Definition BDDconfig := (BDDstate * (BDDsharing_map * ad))%type.

  Definition initBDDconfig :=
    (initBDDstate, (initBDDsharing_map, ad_S (ad_S N0))).

  Definition BDDconfig_OK (cfg : BDDconfig) :=
    match cfg return Prop with
    | (bs, (share, counter)) =>
        BDDstate_OK bs /\
        BDDsharing_OK bs share /\
        (forall a : ad, Nleb counter a = true -> MapGet _ bs a = None) /\
        Nleb (ad_S (ad_S N0)) counter = true
    end.

  Lemma initBDDconfig_OK : BDDconfig_OK initBDDconfig.
  Proof.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDconfig_OK, initBDDconfig in |- *. split. exact initBDDstate_OK.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    split. exact initBDDsharing_map_OK. split. intros a H. simpl in |- *. trivial. trivial.
  Qed.

  Lemma config_OK_zero :
   forall cfg : BDDconfig,
   BDDconfig_OK cfg -> MapGet _ (fst cfg) BDDzero = None.
  Proof.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  intros share counter.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H.  elim H.  intros H0 H1.  elim H0.  intros H2 H3.  simpl in |- *.  exact H2.
  Qed.

  Lemma config_OK_one :
   forall cfg : BDDconfig,
   BDDconfig_OK cfg -> MapGet _ (fst cfg) BDDone = None.
  Proof.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  intros share counter.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H.  elim H.  intros H0 H1.  elim H0.  intros H2 H3.  simpl in |- *.  exact (proj1 H3).
  Qed.

  Definition BDDalloc (cfg : BDDconfig) (x : BDDvar) 
    (l r : ad) :=
    match cfg with
    | (bs, (share, counter)) =>
        let share' := BDDshare_put share x l r counter in
        let bs' := MapPut _ bs counter (x, (l, r)) in
        let counter' := ad_S counter in (bs', (share', counter'), counter)
    end.

  Lemma BDDsharing_lookup_semantics :
   forall (bs : BDDstate) (share : BDDsharing_map) (n l r : ad) (x : BDDvar),
   BDDsharing_OK bs share ->
   (BDDshare_lookup share x l r = Some n <->
    MapGet _ bs n = Some (x, (l, r))).
  Proof.
(* Goal: or (@eq bool false true) (@eq bool false false) *)
    auto.
  Qed.


  Definition node_OK (bs : BDDstate) (node : ad) :=
    node = BDDzero \/ node = BDDone \/ in_dom _ node bs = true.

  Lemma BDDbounded_node_OK :
   forall (bs : BDDstate) (node : ad) (n : BDDvar),
   BDDbounded bs node n -> node_OK bs node.
  Proof.
(* Goal: forall (bs : BDDstate) (node : ad) (n : BDDvar) (_ : BDDbounded bs node n), node_OK bs node *)
    intros bs node n H.
    cut
     (node = BDDzero \/
      node = BDDone \/
      (exists x : BDDvar,
         (exists l : BDDvar,
            (exists r : BDDvar,
               MapGet _ bs node = Some (x, (l, r)) /\
               BDDcompare x n = Datatypes.Lt /\
(* Goal: or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
               Neqb l r = false /\ BDDbounded bs l x /\ BDDbounded bs r x)))).  intros H0.  elim H0; intro.  left.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    elim H1; intro.  right; left; assumption.  inversion H2.  inversion H3.
(* Goal: or (@eq ad x0 BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) x0 bs) true) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    inversion H4.  right; right.  unfold in_dom in |- *.  rewrite (proj1 H5); reflexivity.  apply BDDbounded_lemma.  assumption.
  Qed.

  Lemma BDDalloc_allocates :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   MapGet _ (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)) =
   Some (x, (l, r)).
  Proof.
(* Goal: forall (x : BDDvar) (l r _ : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) y y0)), and (forall (a0 : ad) (_ : @eq bool (Nleb (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r)))) a0) true), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r))) a0) (@None (prod BDDvar (prod ad ad)))) (@eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y y0) x l r))))) true) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y0.  elim y0.  clear y0.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros share counter l r x.  simpl in |- *.
    rewrite
     (MapPut_semantics (BDDvar * (ad * ad)) bs counter (x, (l, r)) counter)
     .
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    cut (Neqb counter counter = true).  intro H.  rewrite H.  trivial.
(* Goal: @eq bool (N.eqb counter counter) true *)
    apply Neqb_correct.
  Qed.

  Lemma BDDalloc_preserves_nodes :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   forall (a l1 r1 : ad) (x1 : BDDvar),
   MapGet _ (fst cfg) a = Some (x1, (l1, r1)) ->
   MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)).
  Proof.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  intros y0 y1 l r x H a l1 r1 x1 H0.  elim H.  clear H.  intros H H1.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) y y1 (x, (l, r)) a).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb y1 a = false).  intro H2.  rewrite H2.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb y1 a <> true).  intros H2.  apply not_true_is_false.  assumption.
(* Goal: @eq bool (Nleb (Npos (xO xH)) (ad_S y1)) true *)
    unfold not in |- *.  intros H2.  elim H1.  intros H3 H4.  elim H4.  intros H5 H6.  lapply (H5 a).
(* Goal: False *)
(* Goal: @eq bool (Nleb y1 a) true *)
    intros H7.  rewrite H7 in H0.  discriminate H0.  lapply (Neqb_complete y1 a).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H7.  rewrite H7.  apply Nleb_refl.  assumption.
  Qed.

  Lemma BDDalloc_no_new_node :
   forall (cfg : BDDconfig) (l l1 r r1 a : ad) (x x1 : BDDvar),
   MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)) ->
   a = snd (snd cfg) \/ MapGet _ (fst cfg) a = Some (x1, (l1, r1)).
  Proof.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  clear y.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros share counter l l' r r' a x x'.  simpl in |- *.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) bs counter (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: or (@eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) bs counter (x, (l, r)) a).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    cut (Neqb counter a = true \/ Neqb counter a = false).  intro H.  elim H.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    clear H.  intro H.  left.  rewrite (Neqb_complete counter a).  trivial.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro H0.  rewrite H0.  auto.  elim (Neqb counter a).  auto.
(* Goal: or (@eq bool false true) (@eq bool false false) *)
    auto.
  Qed.

  Lemma BDDalloc_no_new_node_1 :
   forall (cfg : BDDconfig) (l l1 r r1 a : ad) (x x1 : BDDvar),
   MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)) ->
   (x1, (l1, r1)) = (x, (l, r)) \/
   MapGet _ (fst cfg) a = Some (x1, (l1, r1)).
  Proof.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.  simpl in |- *.
(* Goal: forall (b : prod BDDsharing_map ad) (x : BDDvar) (l r _ : ad) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) y b)), and (forall (a0 : ad) (_ : @eq bool (Nleb (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y b) x l r)))) a0) true), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y b) x l r))) a0) (@None (prod BDDvar (prod ad ad)))) (@eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y b) x l r))))) true) *)
    intro y0.  intro y1.  intro l.  intro l1.  intro r.  intro r1.  intro a.  intro x.  intro x1.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) y y1 (x, (l, r)) a).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1))), or (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x1 (@pair ad ad l1 r1)))) *)
    case (Neqb y1 a).  intro H.  left.  injection H.  intros H0 H1 H2.  rewrite H0.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H1.  rewrite H2.  trivial. intros H.  right. assumption.
  Qed.

  Lemma BDDalloc_preserves_zero :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   MapGet _ (fst (fst (BDDalloc cfg x l r))) BDDzero = None.
  Proof.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros y0 y1 l r x H.  simpl in |- *.  elim H.  clear H.  intros H H0.  elim H0.  clear H0.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H0 H1.  elim H1.  clear H1.  intros H1 H2.  clear H1 H0.  elim H.  clear H.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) BDDone) (@None (prod BDDvar (prod ad ad))) *)
    intros H H0.  clear H0.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) BDDzero) (@None (prod BDDvar (prod ad ad))) *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) y y1 (x, (l, r)) BDDzero).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb y1 BDDzero = false).  intro H0.  rewrite H0.  assumption.
(* Goal: forall _ : @eq bool (N.eqb y1 BDDone) true, False *)
    cut (Neqb y1 BDDzero = true -> False).  intro H0.  apply not_true_is_false.
(* Goal: forall _ : @eq bool (N.eqb y1 BDDone) true, False *)
    exact H0.  intro H0.  rewrite (Neqb_complete y1 BDDzero) in H2.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    compute in H2.  discriminate H2.  assumption.
  Qed.

  Lemma BDDalloc_preserves_one :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   MapGet _ (fst (fst (BDDalloc cfg x l r))) BDDone = None.
  Proof.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros y0 y1 l r x H.  simpl in |- *.  elim H.  clear H.  intros H H0.  elim H0.  clear H0.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H0 H1.  elim H1.  clear H1.  intros H1 H2.  clear H1 H0.  elim H.  clear H.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H H0.  clear H.  elim H0.  clear H0.  intros H H0.  clear H0.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) BDDone) (@None (prod BDDvar (prod ad ad))) *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) y y1 (x, (l, r)) BDDone).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb y1 BDDone = false).  intro H0.  rewrite H0.  assumption.
(* Goal: forall _ : @eq bool (N.eqb y1 BDDone) true, False *)
    cut (Neqb y1 BDDone = true -> False).  intro H0.  apply not_true_is_false.
(* Goal: forall _ : @eq bool (N.eqb y1 BDDone) true, False *)
    exact H0.  intro H0.  rewrite (Neqb_complete y1 BDDone) in H2.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    compute in H2.  discriminate H2.  assumption.
  Qed.

  Lemma BDDalloc_keeps_state_OK :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   node_OK (fst cfg) l ->
   node_OK (fst cfg) r ->
   Neqb l r <> true ->
   (forall (xl : BDDvar) (ll rl : ad),
    MapGet _ (fst cfg) l = Some (xl, (ll, rl)) ->
    BDDcompare xl x = Datatypes.Lt) ->
   (forall (xr : BDDvar) (lr rr : ad),
    MapGet _ (fst cfg) r = Some (xr, (lr, rr)) ->
    BDDcompare xr x = Datatypes.Lt) ->
   BDDstate_OK (fst (fst (BDDalloc cfg x l r))).
  Proof.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros y0 y1 l r x H H0 H1 H2 H3 H4.  split.  apply BDDalloc_preserves_zero.  assumption.  split.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_preserves_one.  simpl in H0, H1, H3, H4.  assumption.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  simpl in H0, H1, H3, H4.  intros a H5.  unfold BDD_OK in |- *.
(* Goal: BDDordered (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a *)
    unfold BDDordered in |- *.  unfold in_dom in H5.
    elim
     (option_sum _
        (MapGet (BDDvar * (ad * ad))
           (MapPut (BDDvar * (ad * ad)) y y1 (x, (l, r))) a)).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros y2.  elim y2.  clear y2.  intro x0.  elim x0.  intro y2.  intro y3.  elim y3.
(* Goal: forall (a0 b : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad a0 b)))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p1 as p0) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intro y4.  intro y5.  intro y6.  rewrite y6.  clear H5 x0 y3.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim (BDDalloc_no_new_node_1 (y, (y0, y1)) l y4 r y5 a x y2 y6).  intros H5.
(* Goal: @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r) (@Some ad a) *)
(* Goal: @eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)) (@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))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
(* Goal: or (@eq ad a (@snd BDDsharing_map ad (@snd BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))))) (@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) x0 (@pair ad ad l0 r0)))) *)
    injection H5.  clear H5.  intros H5 H6 H7.  rewrite H7.  rewrite H5 in y6.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S x) *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    rewrite H6 in y6.  rewrite H7 in y6.  clear H5 H6 H7.  clear y2 y4 y5.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDbounded_2 with (x := x) (l := l) (r := r).  assumption.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDcompare_succ.  apply not_true_is_false.  assumption.  elim H.
(* Goal: forall (_ : forall _ : @eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))) (_ : forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: BDDsharing_OK bs share *)
(* Goal: forall _ : @eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) bs counter (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: or (@eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    intros H5 H6.  elim H5.  intros H7 H8.  elim H8.  intros H9 H10.  unfold node_OK in H0.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l BDDzero))) BDDzero x *)
(* Goal: forall _ : or (@eq ad r BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) r y) true), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim H0.  intro H11.  rewrite H11.  apply BDDbounded_0.  intros H11.  elim H11.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l BDDone))) BDDone x *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) r y) true, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H12.  rewrite H12.  apply BDDbounded_1.  intros H12.  lapply (H10 l).
(* Goal: forall _ : BDD_OK y a, BDDbounded y a (ad_S y2) *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) a y) true *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H13.  unfold BDD_OK in H10.  unfold BDDordered in H10.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) l y) true *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    unfold in_dom in H12.  clear H11.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) l y) true *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim (option_sum _ (MapGet (BDDvar * (ad * ad)) y l)).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros y2.  elim y2.  clear y2.  intro x0.  elim x0.  clear x0.  intro y2.  intro y3.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 y3)), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim y3.  clear y3.  intros y3 y4 y5.  clear H8.  clear H12.
(* Goal: BDDbounded y a (ad_S y2) *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) a y) true *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    unfold BDD_OK in H13.  unfold BDDordered in H13.  rewrite y5 in H13.
(* Goal: forall _ : or (@eq comparison (BDDcompare (ad_S y2) x) Lt) (@eq N (ad_S y2) x), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y l) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) l y) true *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (BDDcompare_1 y2 x).  intros H8.  elim H8.  intros H11.
(* Goal: forall _ : @eq N (ad_S y2) x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (increase_bound y (ad_S y2) x l).  intros H12.  cut (BDDbounded y l x).
(* Goal: forall _ : BDDbounded y r x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: BDDbounded y r x *)
(* Goal: BDDbounded y r (ad_S y2) *)
(* Goal: forall _ : @eq N (ad_S y2) x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H14.  lapply (boundedness_preservation y (MapPut _ y y1 (x, (l, r)))).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros.  apply H15.  assumption.  intros.
    cut
     (MapGet _ (fst (fst (BDDalloc (y, (y0, y1)) x l r))) a0 =
      Some (x0, (l0, r0))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  trivial.  apply BDDalloc_preserves_nodes.  assumption.  simpl in |- *.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  exact (H12 H11).  assumption.  intros.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y l) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) l x *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) l y) true *)
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    rewrite H11 in H13.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (boundedness_preservation y (MapPut _ y y1 (x, (l, r)))).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros.  apply H12.  assumption.  intros.
    cut
     (MapGet _ (fst (fst (BDDalloc (y, (y0, y1)) x l r))) a0 =
      Some (x0, (l0, r0))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  trivial.  apply BDDalloc_preserves_nodes.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  apply H3 with (xl := y2) (ll := y3) (rl := y4).  assumption.  intro y2.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite y2 in H12.  discriminate H12.  assumption.  unfold node_OK in H1.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l BDDzero))) BDDzero x *)
(* Goal: forall _ : or (@eq ad r BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) r y) true), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim H1.  intro H5.  rewrite H5.  apply BDDbounded_0.  intros H5.  elim H5.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l BDDone))) BDDone x *)
(* Goal: forall _ : @eq bool (in_dom (prod BDDvar (prod ad ad)) r y) true, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    clear H5.  intros H5.  rewrite H5.  apply BDDbounded_1.  intros H6.
(* Goal: forall (_ : forall _ : @eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))) (_ : forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: BDDsharing_OK bs share *)
(* Goal: forall _ : @eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) bs counter (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: or (@eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    unfold in_dom in H6.  clear H5.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    elim (option_sum _ (MapGet (BDDvar * (ad * ad)) y r)).  intros y2.  elim y2.
(* Goal: forall (x0 : prod BDDvar (prod ad ad)) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@Some (prod BDDvar (prod ad ad)) x0)), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    clear y2.  intro x0.  elim x0.  clear x0.  intro y2.  intro y3.  elim y3.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    clear y3.  intros y3 y4 y5.  clear H6.  elim H.  intros H5 H6.  elim H5.  intros H7 H8.
(* Goal: or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a) *)
(* Goal: or (@eq ad a (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x 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')))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@eq ad a (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x 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')))) *)
(* 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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) *)
    elim H8.  clear H8.  intros H8 H9.  unfold in_dom in H9.  lapply (H9 r).
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H10.  unfold BDD_OK in H10.  unfold BDDordered in H10.
(* Goal: forall _ : or (@eq comparison (BDDcompare (ad_S y2) x) Lt) (@eq N (ad_S y2) x), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    rewrite y5 in H10.  lapply (BDDcompare_1 y2 x).  intros H11.  elim H11.
(* Goal: forall _ : @eq N (ad_S y2) x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros H12.  lapply (increase_bound y (ad_S y2) x r).  intros H13.
(* Goal: forall _ : BDDbounded y r x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: BDDbounded y r x *)
(* Goal: BDDbounded y r (ad_S y2) *)
(* Goal: forall _ : @eq N (ad_S y2) x, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    cut (BDDbounded y r x).  intros H14.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (boundedness_preservation y (MapPut _ y y1 (x, (l, r)))).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H15.  apply H15.  assumption.  intros a0 l0 r0 x0 H15.
    cut
     (MapGet _ (fst (fst (BDDalloc (y, (y0, y1)) x l r))) a0 =
      Some (x0, (l0, r0))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  trivial.  apply BDDalloc_preserves_nodes.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  assumption.  exact (H13 H12).  assumption.  intros H12.
(* Goal: BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* Goal: @eq comparison (BDDcompare y2 x) Lt *)
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) y r with | Some a => true | None => false end true *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y r) (@None (prod BDDvar (prod ad ad))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) r x *)
(* 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) y (@pair BDDsharing_map ad y0 y1))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) y2 (@pair ad ad y4 y5))), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    rewrite H12 in H10.
(* Goal: forall _ : BDD_OK y a, BDDbounded y a (ad_S y2) *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) a y) true *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (boundedness_preservation y (MapPut _ y y1 (x, (l, r)))).  intros H13.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply H13.  assumption.  intros a0 l0 r0 x0 H13.
    cut
     (MapGet _ (fst (fst (BDDalloc (y, (y0, y1)) x l r))) a0 =
      Some (x0, (l0, r0))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  trivial.  apply BDDalloc_preserves_nodes.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  assumption.  apply H4 with (xr := y2) (lr := y3) (rr := y4).  assumption.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite y5.  trivial.  intro y2.  rewrite y2 in H6.  discriminate H6.
(* Goal: forall _ : @eq bool (N.eqb counter a) true, @eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) *)
(* Goal: @eq bool (N.eqb counter a) true *)
(* 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))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
(* Goal: or (@eq ad a (@snd BDDsharing_map ad (@snd BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))))) (@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) x0 (@pair ad ad l0 r0)))) *)
    intros H5.  simpl in H5.
(* Goal: forall _ : forall (n : BDDvar) (node : ad) (_ : BDDbounded y node n), BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) node n, BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S y2) *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (boundedness_preservation y (MapPut _ y y1 (x, (l, r)))).  intros H6.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply H6.  elim H.  intros H7 H8.  elim H7.  intros H9 H10.  elim H10.  intros H11 H12.
(* Goal: forall _ : BDD_OK y a, BDDbounded y a (ad_S y2) *)
(* Goal: @eq bool (in_dom (prod BDDvar (prod ad ad)) a y) true *)
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    lapply (H12 a).  intros H13.  unfold BDD_OK in H13.  unfold BDDordered in H13.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite H5 in H13.  assumption.  unfold in_dom in |- *.  rewrite H5.  trivial.
(* Goal: forall (a l0 r0 : ad) (x0 : BDDvar) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) y a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)))), @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@None (prod BDDvar (prod ad ad))), match MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a with | Some (pair n p0 as p) => BDDbounded (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a (ad_S n) | None => True end *)
    intros a0 l0 r0 x0 H6.
    cut
     (MapGet _ (fst (fst (BDDalloc (y, (y0, y1)) x l r))) a0 =
      Some (x0, (l0, r0))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  trivial.  apply BDDalloc_preserves_nodes.  assumption.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  assumption.  intros y2.  rewrite y2.  trivial.
  Qed.

  Lemma BDDalloc_adjusts_counter :
   forall (cfg : BDDconfig) (x : BDDvar) (l r a : ad),
   BDDconfig_OK cfg ->
   (forall a : ad,
    Nleb (snd (snd (fst (BDDalloc cfg x l r)))) a = true ->
    MapGet _ (fst (fst (BDDalloc cfg x l r))) a = None) /\
   Nleb (ad_S (ad_S N0)) (snd (snd (fst (BDDalloc cfg x l r)))) = true.
  Proof.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intro y.  intro y0.  elim y0.  clear y0.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros y0 y1 x l r a H.  split.  simpl in |- *.  intros a0 H0.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) y y1 (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a0) (@None (prod BDDvar (prod ad ad))) *)
(* Goal: @eq bool (Nleb (ad_S (ad_S N0)) (@snd BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) y (@pair BDDsharing_map ad y0 y1)) x l r))))) true *)
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) y y1 (x, (l, r)) a0).
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb y1 a0 = false).  intro H1.  rewrite H1.  elim H.  intros.  elim H3.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros.  elim H5.  intros.  apply H6.  apply ad_S_le_then_le.  assumption.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply ad_S_le_then_neq.  assumption.  simpl in |- *.  elim H.  intros.  elim H1.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros.  elim H3.  intros.  apply le_then_le_S.  assumption.
  Qed.

Lemma BDDalloc_keeps_sharing_OK :
 forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
 BDDconfig_OK cfg ->
 node_OK (fst cfg) l ->
 node_OK (fst cfg) r ->
 (forall (x' : BDDvar) (l' r' a : ad),
  MapGet _ (fst cfg) a = Some (x', (l', r')) ->
  (x, (l, r)) <> (x', (l', r'))) ->
 BDDsharing_OK (fst (fst (BDDalloc cfg x l r)))
   (fst (snd (fst (BDDalloc cfg x l r)))).
Proof.
(* Goal: forall (a : BDDstate) (b : prod BDDsharing_map ad) (l r : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) a b)) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) l) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) a b)) r) (_ : forall (x' : BDDvar) (l' r' a0 : 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) a b)) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))), BDDsharing_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r))) (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) a b) x l r)))) *)
    intro cfg.  elim cfg.  clear cfg.  intro bs.  intro y.  elim y.  clear y.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros share counter.  split.  simpl in |- *.  intros H3.
    cut
     (BDDshare_lookup share x0 l0 r0 = Some a \/
      (x, (l, r)) = (x0, (l0, r0))).
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H4.  elim H4.  clear H4.  intros H4.
(* Goal: forall _ : @eq bool (N.eqb l r) false, and (BDDconfig_OK (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (MapGet _ bs a = Some (x0, (l0, r0))).  intro H5.
    change
      (MapGet (BDDvar * (ad * ad))
         (fst (fst (BDDalloc (bs, (share, counter)) x l r))) a =
       Some (x0, (l0, r0))) in |- *.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_preserves_nodes.  assumption.  exact H5.
(* Goal: forall _ : @eq bool (N.eqb l r) false, and (BDDconfig_OK (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    lapply (BDDsharing_lookup_semantics bs share a l0 r0 x0).  intro H5.  elim H5.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    clear H5.  intros H5 H6.  apply H5.  assumption. exact (proj1 (proj2 H)).
(* Goal: forall _ : @eq bool (N.eqb l r) false, and (BDDconfig_OK (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H5.  clear H4.  rewrite <- H5.  injection H5.  intros H4 H6 H7.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) bs counter (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: or (@eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    rewrite <- H4 in H3.  rewrite <- H6 in H3.  rewrite <- H7 in H3.
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (MapPut (prod BDDvar (prod ad ad)) bs counter (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: or (@eq (option ad) (BDDshare_lookup share x0 l0 r0) (@Some ad a)) (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
    rewrite (BDDshare_put_puts share x l r counter) in H3.  injection H3.
(* Goal: forall _ : or (@eq ad a (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x 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')))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a) *)
(* Goal: or (@eq ad a (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x 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')))) *)
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@eq ad a (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x 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')))) *)
(* 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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) *)
    intro H8.  rewrite (MapPut_semantics (BDDvar * (ad * ad)) bs counter (x, (l, r)) a).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb counter a = true).  intro H9.  rewrite H9.  trivial.  rewrite H8.
(* Goal: @eq bool (N.eqb counter counter) true *)
    apply Neqb_correct.  
    apply
     BDDshare_put_no_new_node
      with (x' := x0) (l' := l0) (r' := r0) (counter := counter).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro H3.
    cut
     (a = snd (snd (bs, (share, counter))) \/
      MapGet _ (fst (bs, (share, counter))) a = Some (x0, (l0, r0))).
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))), @eq bool match MapGet (prod BDDvar (prod ad ad)) bs x0 with | Some a => true | None => false end true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H4.  elim H4.  clear H4.  intro H4.  cut ((x0, (l0, r0)) = (x, (l, r))).  intro H5.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    injection H5.  intros H6 H7 H8.  rewrite H6.  rewrite H7.  rewrite H8.  simpl in |- *.
(* Goal: @eq bool match MapGet (prod BDDvar (prod ad ad)) bs x0 with | Some a => true | None => false end true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in H4.  rewrite H4.  apply BDDshare_put_puts.  simpl in H3.
    rewrite (MapPut_semantics (BDDvar * (ad * ad)) bs counter (x, (l, r)) a)
      in H3.
(* Goal: forall _ : @eq bool (N.eqb counter a) true, @eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) *)
(* Goal: @eq bool (N.eqb counter a) true *)
(* 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))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x0 (@pair ad ad l0 r0))), @eq (option ad) (BDDshare_lookup (@fst BDDsharing_map N (@snd (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) x0 l0 r0) (@Some ad a) *)
(* Goal: or (@eq ad a (@snd BDDsharing_map ad (@snd BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))))) (@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) x0 (@pair ad ad l0 r0)))) *)
    simpl in H4.  cut (Neqb counter a = true).  intros H5.  rewrite H5 in H3.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    inversion H3.  trivial.  rewrite H4.  apply Neqb_correct.  intro H5.
(* Goal: forall _ : @sig ad (fun y : ad => @eq (option ad) (BDDshare_lookup share x l r) (@Some ad y)), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a0 l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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))) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))) (@eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a0)) (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))) a0) (@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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    clear H4.
    cut
     (BDDshare_lookup (fst (snd (bs, (share, counter)))) x0 l0 r0 = Some a).
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H4.  simpl in |- *.  simpl in H4.  apply BDDshare_put_preserves_nodes.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  apply H2 with (a := a).  assumption.  elim H.  intros H4 H6.  elim H6.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros.  simpl in |- *.  simpl in H5.  unfold BDDsharing_OK in H7.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold iff in H7.  apply (proj2 (H7 x0 l0 r0 a)).  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_no_new_node with (x := x) (l := l) (r := r).  assumption.
Qed.

  Lemma BDDalloc_semantics :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   node_OK (fst cfg) l ->
   node_OK (fst cfg) r ->
   Neqb l r <> true ->
   (forall (xl : BDDvar) (ll rl : ad),
    MapGet _ (fst cfg) l = Some (xl, (ll, rl)) ->
    BDDcompare xl x = Datatypes.Lt) ->
   (forall (xr : BDDvar) (lr rr : ad),
    MapGet _ (fst cfg) r = Some (xr, (lr, rr)) ->
    BDDcompare xr x = Datatypes.Lt) ->
   (forall (x' : BDDvar) (l' r' a : ad),
    MapGet _ (fst cfg) a = Some (x', (l', r')) ->
    (x, (l, r)) <> (x', (l', r'))) ->
   BDDconfig_OK (fst (BDDalloc cfg x l r)) /\
   MapGet _ (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)) =
   Some (x, (l, r)) /\
   (forall (a l' r' : ad) (x' : BDDvar),
    (MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x', (l', r')) ->
     MapGet _ (fst cfg) a = Some (x', (l', r')) \/
     snd (BDDalloc cfg x l r) = a) /\
    (MapGet _ (fst cfg) a = Some (x', (l', r')) ->
     MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x', (l', r')))) /\
   node_OK (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)). 

  Proof.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  clear y.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros share counter l r x.  intros.  split.  unfold BDDconfig_OK in |- *.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in |- *.  split.
    change (BDDstate_OK (fst (fst (BDDalloc (bs, (share, counter)) x l r))))
     in |- *.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_keeps_state_OK.  assumption.  assumption.  assumption.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  assumption.  assumption.  split.
    change
      (BDDsharing_OK (fst (fst (BDDalloc (bs, (share, counter)) x l r)))
         (fst (snd (fst (BDDalloc (bs, (share, counter)) x l r))))) 
     in |- *.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_keeps_sharing_OK.  assumption.  assumption.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.
    change
      ((forall a : ad,
        Nleb (snd (snd (fst (BDDalloc (bs, (share, counter)) x l r)))) a =
        true ->
        MapGet _ (fst (fst (BDDalloc (bs, (share, counter)) x l r))) a =
        None) /\
       Nleb (ad_S (ad_S N0))
         (snd (snd (fst (BDDalloc (bs, (share, counter)) x l r)))) = true)
     in |- *.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_adjusts_counter.  assumption.  assumption.  split.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    apply BDDalloc_allocates.  split.  split.
    cut
     (MapGet (BDDvar * (ad * ad))
        (fst (fst (BDDalloc (bs, (share, counter)) x l r))) a =
      Some (x', (l', r')) ->
      a = snd (BDDalloc (bs, (share, counter)) x l r) \/
      MapGet (BDDvar * (ad * ad)) (fst (bs, (share, counter))) a =
      Some (x', (l', r'))).
(* 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 (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intros H6 H7.
    cut
     (a = snd (BDDalloc (bs, (share, counter)) x l r) \/
      MapGet (BDDvar * (ad * ad)) (fst (bs, (share, counter))) a =
      Some (x', (l', r'))).
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H8.  elim H8.  right.  rewrite H9.  trivial.  auto.  apply H6.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  intro H6.
    cut
     (a = snd (snd (bs, (share, counter))) \/
      MapGet _ (fst (bs, (share, counter))) a = Some (x', (l', r'))).
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    tauto.  apply BDDalloc_no_new_node with (x := x) (l := l) (r := r).  assumption.
    exact
     (BDDalloc_preserves_nodes (bs, (share, counter)) l r x H a l' r' x').
(* Goal: or (@eq ad x0 BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) x0 bs) true) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold node_OK in |- *.  right.  right.  unfold in_dom in |- *.  simpl in |- *.
    rewrite
     (MapPut_semantics (BDDvar * (ad * ad)) bs counter (x, (l, r)) counter)
     .
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb counter counter = true).  intro H6.  rewrite H6.  trivial.
(* Goal: @eq bool (N.eqb counter counter) true *)
    apply Neqb_correct.
  Qed.

  Definition BDDmake (cfg : BDDconfig) (x : BDDvar) 
    (l r : ad) :=
    if Neqb l r
    then (cfg, l)
    else
     match cfg with
     | (bs, (share, counter)) =>
         match BDDshare_lookup share x l r with
         | Some y => (cfg, y)
         | None => BDDalloc cfg x l r
         end
     end.

  Lemma BDDmake_semantics :
   forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
   BDDconfig_OK cfg ->
   node_OK (fst cfg) l ->
   node_OK (fst cfg) r ->
   (forall (xl : BDDvar) (ll rl : ad),
    MapGet _ (fst cfg) l = Some (xl, (ll, rl)) ->
    BDDcompare xl x = Datatypes.Lt) ->
   (forall (xr : BDDvar) (lr rr : ad),
    MapGet _ (fst cfg) r = Some (xr, (lr, rr)) ->
    BDDcompare xr x = Datatypes.Lt) ->
   BDDconfig_OK (fst (BDDmake cfg x l r)) /\
   (Neqb l r = false ->
    MapGet _ (fst (fst (BDDmake cfg x l r))) (snd (BDDmake cfg x l r)) =
    Some (x, (l, r))) /\
   (Neqb l r = true -> snd (BDDmake cfg x l r) = l) /\
   (forall (a l' r' : ad) (x' : BDDvar),
    (MapGet _ (fst (fst (BDDmake cfg x l r))) a = Some (x', (l', r')) ->
     MapGet _ (fst cfg) a = Some (x', (l', r')) \/
     snd (BDDmake cfg x l r) = a) /\
    (MapGet _ (fst cfg) a = Some (x', (l', r')) ->
     MapGet _ (fst (fst (BDDmake cfg x l r))) a = Some (x', (l', r')))) /\
   node_OK (fst (fst (BDDmake cfg x l r))) (snd (BDDmake cfg x l r)).
  Proof.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro cfg.  elim cfg.  clear cfg.  intros bs y.  elim y.  clear y.
(* Goal: forall (a : BDDsharing_map) (b l r : ad) (x : BDDvar) (_ : BDDconfig_OK (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b))) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b))) l) (_ : node_OK (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b))) r) (_ : forall (xl : BDDvar) (ll rl : 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 a b))) l) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xl (@pair ad ad ll rl)))), @eq comparison (BDDcompare xl x) Lt) (_ : forall (xr : BDDvar) (lr rr : 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 a b))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt), and (BDDconfig_OK (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r)) l) (and (forall (a0 l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 a b))) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r')))) (@eq ad (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r)) a0)) (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 a b))) a0) (@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) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) a0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r))) (@snd BDDconfig ad (BDDmake (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad a b)) x l r)))))) *)
    intros share counter l r x.  intros H H0 H1 H2 H3.
(* Goal: forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))), @eq bool match MapGet (prod BDDvar (prod ad ad)) bs x0 with | Some a => true | None => false end true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (Neqb l r = true \/ Neqb l r = false).  intro H4.  elim H4.  clear H4.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H4.  unfold BDDmake in |- *.  rewrite H4.  split.  assumption.  split.  intro H5.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    discriminate H5.  split.  simpl in |- *.  auto.  split.  simpl in |- *.  auto.  simpl in |- *.
(* Goal: and (BDDconfig_OK (@fst BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) (and (forall _ : @eq bool (N.eqb l r) false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) (@snd BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool (N.eqb l r) true, @eq ad (@snd BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a)) (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))) 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) (@fst BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))) (@snd BDDconfig ad (if N.eqb l r then @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) l else match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    exact H0.  intro H5.  unfold BDDmake in |- *.  rewrite H5.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    elim (option_sum _ (BDDshare_lookup share x l r)).  clear H4.  intro y.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    elim y.  clear y.  intro x0.  intro y.  rewrite y.  split.  simpl in |- *.  exact H.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    split.  intro H4.  elim H.  intros H6 H7.  elim H7.  intros H8 H9.
(* Goal: and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0)) a)) (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))) 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) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) (@snd BDDconfig ad (@pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x0))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    unfold BDDsharing_OK in H8.  simpl in |- *.  apply (proj1 (H8 x l r x0)).
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  split.  intro H4.  discriminate H4.  simpl in |- *.  split.  intros a l' r' x'.
(* Goal: or (@eq ad x0 BDDone) (@eq bool (in_dom (prod BDDvar (prod ad ad)) x0 bs) true) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    tauto.  unfold node_OK in |- *.  right.  right.  unfold in_dom in |- *.
(* Goal: @eq bool true true *)
(* Goal: @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) bs x0) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r))) *)
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@None ad), and (BDDconfig_OK (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (and (forall _ : @eq bool false false, @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end) a)) (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))) 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) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end)) (@snd BDDconfig ad match BDDshare_lookup share x l r with | Some y => @pair BDDconfig ad (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) y | None => BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r end))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (MapGet _ bs x0 = Some (x, (l, r))).  intro H4.  rewrite H4.  trivial.  
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    elim H.  intros H4 H6.  exact (proj1 (proj1 H6 x l r x0) y).  intro y.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a), False *)
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    rewrite y.
    cut
     (BDDconfig_OK (fst (BDDalloc (bs, (share, counter)) x l r)) /\
      MapGet _ (fst (fst (BDDalloc (bs, (share, counter)) x l r)))
        (snd (BDDalloc (bs, (share, counter)) x l r)) = 
      Some (x, (l, r)) /\
      (forall (a l' r' : ad) (x' : BDDvar),
       (MapGet _ (fst (fst (BDDalloc (bs, (share, counter)) x l r))) a =
        Some (x', (l', r')) ->
        MapGet _ (fst (bs, (share, counter))) a = Some (x', (l', r')) \/
        snd (BDDalloc (bs, (share, counter)) x l r) = a) /\
       (MapGet _ (fst (bs, (share, counter))) a = Some (x', (l', r')) ->
        MapGet _ (fst (fst (BDDalloc (bs, (share, counter)) x l r))) a =
        Some (x', (l', r')))) /\
      node_OK (fst (fst (BDDalloc (bs, (share, counter)) x l r)))
        (snd (BDDalloc (bs, (share, counter)) x l r))).
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    intro H6.  split.  exact (proj1 H6).  split.  intro H7.
(* Goal: and (forall _ : @eq bool false true, @eq ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) l) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst BDDstate (prod BDDsharing_map ad) (@fst BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd BDDconfig ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)))) *)
(* Goal: and (BDDconfig_OK (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (and (@eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)))) (and (forall (a l' r' : ad) (x' : BDDvar), and (forall _ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))), or (@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 ad (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r)) a)) (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))) 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 (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) a) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))))) (node_OK (@fst (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N) (@fst (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))) (@snd (prod (Map (prod BDDvar (prod ad ad))) (prod BDDsharing_map N)) ad (BDDalloc (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter)) x l r))))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    exact (proj1 (proj2 H6)).  split.  intro H7.  discriminate H7.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    exact (proj2 (proj2 H6)).  apply BDDalloc_semantics.  assumption.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    assumption.  assumption.  unfold not in |- *.  intro.  rewrite H5 in H6.
(* Goal: forall (xr : BDDvar) (lr rr : ad) (_ : @eq (option (prod BDDvar (prod ad ad))) (MapGet (prod BDDvar (prod ad ad)) (@fst BDDstate (prod BDDsharing_map ad) (@pair BDDstate (prod BDDsharing_map ad) bs (@pair BDDsharing_map ad share counter))) r) (@Some (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) xr (@pair ad ad lr rr)))), @eq comparison (BDDcompare xr x) Lt *)
(* Goal: forall (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')))), not (@eq (prod BDDvar (prod ad ad)) (@pair BDDvar (prod ad ad) x (@pair ad ad l r)) (@pair BDDvar (prod ad ad) x' (@pair ad ad l' r'))) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    discriminate H6.  assumption.  assumption.  intros.  unfold not in |- *.  intros.
(* Goal: False *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    simpl in H6.  rewrite <- H7 in H6.
(* Goal: forall _ : @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a), False *)
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    cut (BDDshare_lookup share x l r = Some a).  rewrite y.  discriminate.
(* Goal: @eq (option ad) (BDDshare_lookup share x l r) (@Some ad a) *)
(* Goal: or (@eq bool (N.eqb l r) true) (@eq bool (N.eqb l r) false) *)
    elim H.  intros H8 H9.  elim H9.  intros H10 H11.  unfold BDDsharing_OK in H10.
(* Goal: or (@eq bool false true) (@eq bool false false) *)
    exact (proj2 (H10 x l r a) H6).  elim (Neqb l r).  auto.  auto.
  Qed.
