(* 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                                                     *)
Inductive BDDdummy_type1 : Set :=
BDDdummy1 : BDDconfig * ad * BDDneg_memo -> BDDdummy_type1.
Inductive BDDdummy_type2 : Set :=
BDDdummy2 : BDDconfig * ad -> BDDdummy_type2.
Inductive BDDdummy_type3 : Set :=
BDDdummy3 : BDDconfig * (ad * BDDor_memo) -> BDDdummy_type3.
Definition initBDDneg_memo : BDDneg_memo := newMap ad.
Fixpoint BDDneg_1_1 (cfg : BDDconfig) (memo : BDDneg_memo)
(node : ad) (bound : nat) {struct bound} : BDDconfig * ad * BDDneg_memo :=
match BDDneg_memo_lookup memo node with
| Some node' => (cfg, node', memo)
| None =>
match MapGet _ (fst cfg) node with
| None =>
if N.eqb node BDDzero
then (cfg, BDDone, BDDneg_memo_put memo BDDzero BDDone)
else (cfg, BDDzero, BDDneg_memo_put memo BDDone BDDzero)
| Some (x, (l, r)) =>
match bound with
| O => (initBDDconfig, BDDzero, initBDDneg_memo)
| S bound' =>
match BDDdummy1 (BDDneg_1_1 cfg memo l bound') with
| BDDdummy1 ((cfgl, nodel), memol) =>
match BDDdummy1 (BDDneg_1_1 cfgl memol r bound') with
| BDDdummy1 ((cfgr, noder), memor) =>
match BDDdummy2 (BDDmake cfgr x nodel noder) with
| BDDdummy2 (cfg', node') =>
(cfg', node', BDDneg_memo_put memor node node')
end
end
end
end
end
end.
Fixpoint BDDor_1_1 (cfg : BDDconfig) (memo : BDDor_memo)
(node1 node2 : ad) (bound : nat) {struct bound} :
BDDconfig * (ad * BDDor_memo) :=
match BDDor_memo_lookup memo node1 node2 with
| Some node => (cfg, (node, memo))
| None =>
if N.eqb node1 BDDzero
then (cfg, (node2, BDDor_memo_put memo BDDzero node2 node2))
else
if N.eqb node1 BDDone
then (cfg, (BDDone, BDDor_memo_put memo BDDone node2 BDDone))
else
if N.eqb node2 BDDzero
then (cfg, (node1, BDDor_memo_put memo node1 BDDzero node1))
else
if N.eqb node2 BDDone
then (cfg, (BDDone, BDDor_memo_put memo node1 BDDone BDDone))
else
match bound with
| O => (initBDDconfig, (BDDzero, initBDDor_memo))
| S bound' =>
match BDDcompare (var cfg node1) (var cfg node2) with
| Datatypes.Eq =>
match
BDDdummy3
(BDDor_1_1 cfg memo (low cfg node1)
(low cfg node2) bound')
with
| BDDdummy3 (cfgl, (nodel, memol)) =>
match
BDDdummy3
(BDDor_1_1 cfgl memol (high cfg node1)
(high cfg node2) bound')
with
| BDDdummy3 (cfgr, (noder, memor)) =>
match
BDDdummy2
(BDDmake cfgr (var cfg node1) nodel noder)
with
| BDDdummy2 (cfg', node') =>
(cfg',
(node', BDDor_memo_put memor node1 node2 node'))
end
end
end
| Datatypes.Lt =>
match
BDDdummy3
(BDDor_1_1 cfg memo node1 (low cfg node2) bound')
with
| BDDdummy3 (cfgl, (nodel, memol)) =>
match
BDDdummy3
(BDDor_1_1 cfgl memol node1 (high cfg node2) bound')
with
| BDDdummy3 (cfgr, (noder, memor)) =>
match
BDDdummy2
(BDDmake cfgr (var cfg node2) nodel noder)
with
| BDDdummy2 (cfg', node') =>
(cfg',
(node', BDDor_memo_put memor node1 node2 node'))
end
end
end
| Datatypes.Gt =>
match
BDDdummy3
(BDDor_1_1 cfg memo (low cfg node1) node2 bound')
with
| BDDdummy3 (cfgl, (nodel, memol)) =>
match
BDDdummy3
(BDDor_1_1 cfgl memol (high cfg node1) node2 bound')
with
| BDDdummy3 (cfgr, (noder, memor)) =>
match
BDDdummy2
(BDDmake cfgr (var cfg node1) nodel noder)
with
| BDDdummy2 (cfg', node') =>
(cfg',
(node', BDDor_memo_put memor node1 node2 node'))
end
end
end
end
end
end.

Lemma prod_sum :
forall (A B : Set) (p : A * B), exists a : A, (exists b : B, p = (a, b)).