From d77074b341b21bf4aee52be852bc09b2eb96e959 Mon Sep 17 00:00:00 2001 From: Ludovic Jacomme Date: Wed, 3 Apr 2002 13:13:26 +0000 Subject: [PATCH] Hi --- alliance/src/log/Makefile.am | 1 + alliance/src/log/configure.in | 47 + alliance/src/log/man1/Makefile.am | 1 + alliance/src/log/man1/log.1 | 38 + alliance/src/log/man3/Makefile.am | 6 + alliance/src/log/man3/ablToBddCct.3 | 57 + alliance/src/log/man3/addListBdd.3 | 63 + alliance/src/log/man3/applyBdd.3 | 77 + alliance/src/log/man3/applyBinBdd.3 | 59 + alliance/src/log/man3/bddToAblCct.3 | 58 + alliance/src/log/man3/composeBdd.3 | 60 + alliance/src/log/man3/constraintBdd.3 | 58 + alliance/src/log/man3/createNodeTermBdd.3 | 50 + alliance/src/log/man3/destroyBdd.3 | 39 + alliance/src/log/man3/displayBdd.3 | 66 + alliance/src/log/man3/gcNodeBdd.3 | 59 + alliance/src/log/man3/initializeBdd.3 | 48 + alliance/src/log/man3/markAllBdd.3 | 28 + alliance/src/log/man3/markBdd.3 | 32 + alliance/src/log/man3/notBdd.3 | 48 + alliance/src/log/man3/numberNodeAllBdd.3 | 51 + alliance/src/log/man3/numberNodeBdd.3 | 56 + alliance/src/log/man3/resetBdd.3 | 39 + alliance/src/log/man3/simplifDcOneBdd.3 | 50 + alliance/src/log/man3/simplifDcZeroBdd.3 | 57 + alliance/src/log/man3/supportChain_listBdd.3 | 65 + alliance/src/log/man3/upVarBdd.3 | 64 + alliance/src/log/src/Makefile.am | 27 + alliance/src/log/src/log.h | 424 ++++ alliance/src/log/src/log_bdd0.c | 1912 ++++++++++++++++ alliance/src/log/src/log_bdd1.c | 739 ++++++ alliance/src/log/src/log_prefbib.c | 2138 ++++++++++++++++++ alliance/src/log/src/log_thash.c | 379 ++++ alliance/src/log/src/log_thashbdd.c | 352 +++ alliance/src/log/src/log_thashloc.c | 241 ++ 35 files changed, 7489 insertions(+) create mode 100644 alliance/src/log/Makefile.am create mode 100644 alliance/src/log/configure.in create mode 100644 alliance/src/log/man1/Makefile.am create mode 100644 alliance/src/log/man1/log.1 create mode 100644 alliance/src/log/man3/Makefile.am create mode 100644 alliance/src/log/man3/ablToBddCct.3 create mode 100644 alliance/src/log/man3/addListBdd.3 create mode 100644 alliance/src/log/man3/applyBdd.3 create mode 100644 alliance/src/log/man3/applyBinBdd.3 create mode 100644 alliance/src/log/man3/bddToAblCct.3 create mode 100644 alliance/src/log/man3/composeBdd.3 create mode 100644 alliance/src/log/man3/constraintBdd.3 create mode 100644 alliance/src/log/man3/createNodeTermBdd.3 create mode 100644 alliance/src/log/man3/destroyBdd.3 create mode 100644 alliance/src/log/man3/displayBdd.3 create mode 100644 alliance/src/log/man3/gcNodeBdd.3 create mode 100644 alliance/src/log/man3/initializeBdd.3 create mode 100644 alliance/src/log/man3/markAllBdd.3 create mode 100644 alliance/src/log/man3/markBdd.3 create mode 100644 alliance/src/log/man3/notBdd.3 create mode 100644 alliance/src/log/man3/numberNodeAllBdd.3 create mode 100644 alliance/src/log/man3/numberNodeBdd.3 create mode 100644 alliance/src/log/man3/resetBdd.3 create mode 100644 alliance/src/log/man3/simplifDcOneBdd.3 create mode 100644 alliance/src/log/man3/simplifDcZeroBdd.3 create mode 100644 alliance/src/log/man3/supportChain_listBdd.3 create mode 100644 alliance/src/log/man3/upVarBdd.3 create mode 100644 alliance/src/log/src/Makefile.am create mode 100644 alliance/src/log/src/log.h create mode 100644 alliance/src/log/src/log_bdd0.c create mode 100644 alliance/src/log/src/log_bdd1.c create mode 100644 alliance/src/log/src/log_prefbib.c create mode 100644 alliance/src/log/src/log_thash.c create mode 100644 alliance/src/log/src/log_thashbdd.c create mode 100644 alliance/src/log/src/log_thashloc.c diff --git a/alliance/src/log/Makefile.am b/alliance/src/log/Makefile.am new file mode 100644 index 00000000..20db1515 --- /dev/null +++ b/alliance/src/log/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src man1 man3 diff --git a/alliance/src/log/configure.in b/alliance/src/log/configure.in new file mode 100644 index 00000000..978f8ec3 --- /dev/null +++ b/alliance/src/log/configure.in @@ -0,0 +1,47 @@ +dnl +/* +dnl This file is part of the Alliance CAD System +dnl Copyright (C) Laboratoire LIP6 - Département ASIM +dnl Universite Pierre et Marie Curie +dnl +dnl Home page : http://www-asim.lip6.fr/alliance/ +dnl E-mail support : mailto:alliance-support@asim.lip6.fr +dnl +dnl This library is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU Library General Public License as published +dnl by the Free Software Foundation; either version 2 of the License, or (at +dnl your option) any later version. +dnl +dnl Alliance VLSI CAD System is distributed in the hope that it will be +dnl useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +dnl Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with the GNU C Library; see the file COPYING. If not, write to the Free +dnl Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +dnl +dnl Purpose : Auto stuffing Alliance +dnl Almost ten years since I wrote this stuff, I just can't +dnl believe it +dnl Date : 01/02/2002 +dnl Author : Frederic Petrot +dnl $Id: configure.in,v 1.1 2002/04/03 13:13:25 ludo Exp $ +dnl +dnl +AC_INIT(src/log.h) +AM_INIT_AUTOMAKE(log, 2.1) +AC_PROG_INSTALL +AC_PROG_CC +AC_HEADER_STDC +AC_C_CONST +AC_PROG_RANLIB + +AM_ALLIANCE + +AC_OUTPUT([ +Makefile +src/Makefile +man1/Makefile +man3/Makefile +]) diff --git a/alliance/src/log/man1/Makefile.am b/alliance/src/log/man1/Makefile.am new file mode 100644 index 00000000..32ecaf3b --- /dev/null +++ b/alliance/src/log/man1/Makefile.am @@ -0,0 +1 @@ +man_MANS = log.1 diff --git a/alliance/src/log/man1/log.1 b/alliance/src/log/man1/log.1 new file mode 100644 index 00000000..651ec54c --- /dev/null +++ b/alliance/src/log/man1/log.1 @@ -0,0 +1,38 @@ +.\" $Id: log.1,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)log.l 0.0 92/08/01 UPMC; Author: Luc Burgun +.pl -.4 +.TH LOG 1 "October 1, 1997" "ASIM/LIP6" "cao\-vlsi reference manual" +.SH NAME +\fBlog\fP \- logical representations for boolean functions and utilities. +.so man1/alc_origin.1 +.SH DESCRIPTION +\fBlog\fP is a set of structures and functions that permits to manipulate several representations of boolean functions. Several programs and libraries of the \fIcao-vlsi cad tools\fP rest on the \fIlog\fP package. Three different kind of functions are available for: +.TP 20 +Hash table management +.TP 20 +Prefixed representation for boolean functions +.TP 20 +Ordered binary decision diagrams representation +.SH EXAMPLE +Let's suppose that actual mbk version is 'nnn'. +In order to use log, \fIlibMutnnn.a\fP library must be called. +.br +\fImakefile\fP: +.br +HEADER = -I/labo/include +.br +LIB = -L/labo/lib -lMutnnn -ltshmmm -lablmmm -lbddmmm +.br +Each library can be called separatly. The "logmmm.h" header file must be inserted in the files that use the functions or the structures defined in a library. +.br +.SH SEE ALSO +.BR mbk (1), +.BR beh (1), +.SH AUTHOR +L. BURGUN salle 30 T. 55-65 Universite P&M Curie - 4 pl. Jussieu - FRANCE +.br +.SH THANKS +Thanks to P. REMY, F. PETROT, P. ALLEGRE and N. DICTUS. + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/Makefile.am b/alliance/src/log/man3/Makefile.am new file mode 100644 index 00000000..0624eb0a --- /dev/null +++ b/alliance/src/log/man3/Makefile.am @@ -0,0 +1,6 @@ +man_MANS = composeBdd.3 initializeBdd.3 resetBdd.3 \ +ablToBddCct.3 constraintBdd.3 markAllBdd.3 simplifDcOneBdd.3 \ +addListBdd.3 createNodeTermBdd.3 markBdd.3 simplifDcZeroBdd.3 \ +applyBdd.3 destroyBdd.3 notBdd.3 supportChain_listBdd.3 \ +applyBinBdd.3 displayBdd.3 numberNodeAllBdd.3 upVarBdd.3 \ +bddToAblCct.3 gcNodeBdd.3 numberNodeBdd.3 diff --git a/alliance/src/log/man3/ablToBddCct.3 b/alliance/src/log/man3/ablToBddCct.3 new file mode 100644 index 00000000..99bcbac7 --- /dev/null +++ b/alliance/src/log/man3/ablToBddCct.3 @@ -0,0 +1,57 @@ +.\" $Id: ablToBddCct.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)ablToBddCct.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH ABLTOBDDCCT 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBablToBddCct\fP \- converts an ABL into a BDD within a circuit +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode ablToBddCct(pC,expr) +pCircuit pC; +chain_list *expr; +.fi +.SH PARAMETERS +.TP 20 +\fIpC\fP +Circuit in which is made the conversion +.TP 20 +\fIexpr\fP +expression to convert +.SH DESCRIPTION +\fBablToBddCct()\fP constructs the graph that is computed from \fIexpr\fP. This function provides the basic method for constructing easily the BDDs. The \fBapplyBdd()\fP function is called recursively by going through the ABL. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +chain_list *expr; +pNode res; +pCircuit pC; + +initializeBdd(SMALL_BDD); +pC = initializeCct("circuit 1",10,10); + +addInputCct(pC,"a"); +addInputCct(pC,"b"); + + /* let's suppose that expr = (OR (AND (NOT a) b) a) */ + +res = ablToBddCct(pC,expr); +displayBdd(res,1); + +/* it will display +@res INDEX = 3 LOW = @nodeA HIGH = ONE +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +*/ + +destroyCct(pC); +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR abl (1), +.BR bddToAblCct (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/addListBdd.3 b/alliance/src/log/man3/addListBdd.3 new file mode 100644 index 00000000..5068fd29 --- /dev/null +++ b/alliance/src/log/man3/addListBdd.3 @@ -0,0 +1,63 @@ +.\" $Id: addListBdd.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)addListBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH ADDLISTBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBaddListBdd\fP \- adds a BDD to a chained list of BDDs +.SH SYNOPSYS +.nf +#include "logmmm.h" +chain_list *addListBdd(pt,pBdd) +chain_list *pt; +pNode pBdd; +.fi +.SH PARAMETERS +.TP 20 +\fIpt\fP +old \fIchain_list\fP pointer +.TP 20 +\fIpBdd\fP +BDD to add +.SH DESCRIPTION +\fBaddListBdd()\fP adds \fIpBdd\fP to \fIpt\fP. This function computes an optimal reordering on \fIpt\fP that minimizes the number of nodes when the \fBapplyBdd()\fP function is called. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; +chain_list *pt; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); +pt = NULL; +pt = addListBdd(pt,nodeA); +pt = addListBdd(pt,nodeB); +pt = addListBdd(pt,nodeC); +res = applyBdd(OR,pt); +displayBdd(res,1); + +/* it will display +@res INDEX = 4 LOW = @inter HIGH = ONE +@inter INDEX = 3 LOW = @nodeA HIGH = ONE +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +*/ +/* total number of nodes = 5 */ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR addListBdd (3), +.BR addListBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/applyBdd.3 b/alliance/src/log/man3/applyBdd.3 new file mode 100644 index 00000000..5d063d77 --- /dev/null +++ b/alliance/src/log/man3/applyBdd.3 @@ -0,0 +1,77 @@ +.\" $Id: applyBdd.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)applyBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH APPLYBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBapplyBdd\fP \- applies an operator to a list of BDD. +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode applyBdd(oper,pt) +short oper; +chain_list *pt; +.fi +.SH PARAMETERS +.TP 20 +\fIoper\fP +operator number to apply (OR,AND,XOR,NAND,NOR,NXOR,NOT) +.TP 20 +\fIpt\fP +\fIchain_list\fP of BDD. +.SH DESCRIPTION +\fBapplyBdd()\fP applies \fIoper\fP to a list of Bdd. This list can be created by \fBaddListBdd()\fP function. This function provides the basic method for creating the representation of a function according to the operators in a boolean expression. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; +chain_list *pt; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); +pt = NULL; +pt = addListBdd(pt,nodeA); +pt = addListBdd(pt,nodeB); +pt = addListBdd(pt,nodeC); +res = applyBdd(OR,pt); +displayBdd(res,1); + +/* it will display +@res INDEX = 4 LOW = @inter HIGH = ONE +@inter INDEX = 3 LOW = @nodeA HIGH = ONE +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +*/ + +destroyBdd(1); +.fi +.SH ERRORS +"applyBdd : error - unknown operator" +.br +the operator number must be in (OR,AND,XOR,NAND,NOR,NXOR,NOT) +.br +"applyBdd : error - chained list is empty" +.br +chained list pointer \fIpt = NULL\fP. +.br +"applyBdd : error - bad operator" +.br +The number of arguments is 1 and the operator is distinct from NOT. +.br +chained list pointer \fIpt = NULL\fP. +.br +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR addListBdd (3), +.BR applyBinBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/applyBinBdd.3 b/alliance/src/log/man3/applyBinBdd.3 new file mode 100644 index 00000000..ac58473f --- /dev/null +++ b/alliance/src/log/man3/applyBinBdd.3 @@ -0,0 +1,59 @@ +.\" $Id: applyBinBdd.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)applyBinBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH APPLYBINBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBapplyBinBdd\fP \- applies an operator to two BDD. +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode applyBinBdd(oper,pBdd1,pBdd2) +short oper; +pNode pBdd1; +pNode pBdd2; +.fi +.SH PARAMETERS +.TP 20 +\fIoper\fP +operator number to apply (OR,AND,XOR,NAND,NOR,NXOR) +.TP 20 +\fIpBdd1\fP +first argument +.TP 20 +\fIpBdd2\fP +second argument +.SH DESCRIPTION +\fBapplyBinBdd()\fP applies \fIoper\fP to \fIpBdd1\fP and \fIpBdd2\fP. This function provides the basic method for creating the representation of a boolean function. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB; +pNode res; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res = applyBinBdd(OR,nodeA,nodeB); +displayBdd(res,1); + +/* it will display +@res INDEX = 3 LOW = @nodeA HIGH = ONE +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR applyBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/bddToAblCct.3 b/alliance/src/log/man3/bddToAblCct.3 new file mode 100644 index 00000000..222cd667 --- /dev/null +++ b/alliance/src/log/man3/bddToAblCct.3 @@ -0,0 +1,58 @@ +.\" $Id: bddToAblCct.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)bddToAblCct.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH BDDTOABLCCT 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBbddToAblCct\fP \- converts a BDD into an ABL within a circuit +.SH SYNOPSYS +.nf +#include "logmmm.h" +chain_list *bddToAblCct(pC,pBdd) +pCircuit pC; +pNode pBdd; +.fi +.SH PARAMETERS +.TP 20 +\fIpC\fP +Circuit in which is made the conversion +.TP 20 +\fIpBdd\fP +BDD to convert +.SH DESCRIPTION +\fBbddToAblCct()\fP converts \fIpBdd\fP into an expression. This function returns a result that depends from the ordering of the primary input. This function provides the basic method for the logical optimizer called in BOP. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +chain_list *expr; +pNode res; +pCircuit pC; + +initializeBdd(SMALL_BDD); +pC = initializeCct("circuit 1",10,10); + +addInputCct(pC,"a"); +addInputCct(pC,"b"); + + /* let's suppose that res = (OR a b) */ + +expr = bddToAblCct(pC,applyBinBdd(OR, + createNodeTermBdd(searchInputCct(pC,"a"))), + createNodeTermBdd(searchInputCct(pC,"b"))); +displayExpr(expr); + +/* it will display +(OR a b) +*/ + +destroyCct(pC); +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR abl (1), +.BR ablToBddCct (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/composeBdd.3 b/alliance/src/log/man3/composeBdd.3 new file mode 100644 index 00000000..803e2388 --- /dev/null +++ b/alliance/src/log/man3/composeBdd.3 @@ -0,0 +1,60 @@ +.\" $Id: composeBdd.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)composeBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH COMPOSEBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBcomposeBdd\fP \- substitutes an index by a BDD in another BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode composeBdd(pBdd1,pBdd2,index) +pNode pBdd1; +pNode pBdd2; +short index; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd1\fP +BDD in wich \fIindex\fP is substituted +.TP 20 +\fIpBdd2\fP +BDD that replaces \fIindex\fP +.TP 20 +\fIindex\fP +index to substitute +.SH DESCRIPTION +\fBcomposeBdd()\fP constructs the graph for the function obtained by composing \fIpBdd1\fP and \fIpBdd2\fP. +This function can be used when an auxiliary variable has been mistaken for a primary input. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB; +pNode res; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res = applyBinBdd(OR,nodeA,nodeB); /* res = (OR a b) */ +res = composeBdd(res,notBdd(nodeB),2); /* composition : a = (NOT B) */ +displayBdd(res,1); + +/* it will display +@res ONE +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR applyBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR applyBinBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/constraintBdd.3 b/alliance/src/log/man3/constraintBdd.3 new file mode 100644 index 00000000..2208bdc6 --- /dev/null +++ b/alliance/src/log/man3/constraintBdd.3 @@ -0,0 +1,58 @@ +.\" $Id: constraintBdd.3,v 1.1 2002/04/03 13:13:25 ludo Exp $ +.\" @(#)constraintBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH CONSTRAINTBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBconstraintBdd\fP \- restricts a BDD to another BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode constraintBdd(pBdd1,pBdd2) +pNode pBdd1; +pNode pBdd2; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd1\fP +BDD to restrict +.TP 20 +\fIpBdd2\fP +constraint BDD +.SH DESCRIPTION +\fBconstraintBdd()\fP constructs the graph for the function obtained by restricting \fIpBdd1\fP on \fIpBdd2\fP. +This function can be used for example when a primary input is stuck at 0 or 1. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB; +pNode res; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res = applyBinBdd(OR,nodeA,nodeB); /* res = (OR a b) +res = constraintBdd(res,nodeA); /* a = 1 */ +displayBdd(res,1); + +/* it will display +@res ONE +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR simplifDcOneBdd (3), +.BR simplifDcZeroBdd (3), +.BR composeBdd (3), +.BR applyBdd (3), +.BR notBdd (3), +.BR applyBinBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/createNodeTermBdd.3 b/alliance/src/log/man3/createNodeTermBdd.3 new file mode 100644 index 00000000..76a35aab --- /dev/null +++ b/alliance/src/log/man3/createNodeTermBdd.3 @@ -0,0 +1,50 @@ +.\" $Id: createNodeTermBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)createNodeTermBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH CREATENODETERMBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBcreateNodeTermBdd\fP \- creates a terminal node of variable. +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode createNodeTermBdd(index) +short index; +.fi +.SH PARAMETER +.TP 20 +\fIindex\fP +associated index +.SH DESCRIPTION +\fBcreateNodeTermBdd()\fP creates a terminal node corresponding to \fIindex\fP. Because of reduction table, this function always returns the same \fIpNode\fP for a given \fIindex\fP. 0 and 1 \fIindex\fP are reserved to the \fIzero\fP and \fIone\fP nodes. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +displayBdd(nodeA,1); + +/* it will display +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +*/ +nodeA = createNodeTermBdd(3); /* nodeA doesn't change */ + +destroyBdd(1); +.fi +.SH ERROR +"createNodeTermBdd : error - index < 2" +.br +\fIindex\fP must be strictly higher than 1. +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR applyBinBdd (3), +.BR applyBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR notBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/destroyBdd.3 b/alliance/src/log/man3/destroyBdd.3 new file mode 100644 index 00000000..7837981d --- /dev/null +++ b/alliance/src/log/man3/destroyBdd.3 @@ -0,0 +1,39 @@ +.\" $Id: destroyBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)destroyBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH DESTROYBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBdestroyBdd\fP \- removes the BDDs system +.SH SYNOPSYS +.nf +#include "logmmm.h" +void destroyBdd(level) +.fi +.SH PARAMETER +.TP 20 +\fIlevel\fP +desallocate level +.SH DESCRIPTION +\fBdestroyBdd()\fP removes the BDDs system. This function can be called only after the \fBinitializeBdd()\fP function. if \fIlevel = 0\fP the nodes are saved and it's possible to go through the BDD for treatements that don't modify the BDD (simulation for example). +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" + +initializeBdd(MEDIUM_BDD); + +/* application using BDD ... */ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR initializeBdd (3), +.BR gcNodeBdd (3), +.BR markAllBdd (3), +.BR numberNodeAllBdd (3), +.BR resetBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/displayBdd.3 b/alliance/src/log/man3/displayBdd.3 new file mode 100644 index 00000000..264f3149 --- /dev/null +++ b/alliance/src/log/man3/displayBdd.3 @@ -0,0 +1,66 @@ +.\" $Id: displayBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)displayBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH DISPLAYBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBdisplayBdd\fP \- displays a BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +void displayBdd(pBdd,level) +pNode pBdd; +int level; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd\fP +BDD to display +.TP 20 +\fIlevel\fP +displaying level +.SH DESCRIPTION +\fBdisplayBdd()\fP displays \fIpBDD\fP. if \fIlevel= 1\fP, this function displays all the nodes of \fIpBdd\fP, if \fIlevel = 0\fP the function displays the root node of \fIpBdd\fP. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); + +res = applyBinBdd(OR,applyBinBdd(AND,nodeB,nodeC),nodeA); + /* corresponding to (OR (AND b c) a) */ + +displayBdd(res,1); + +/* it will display +@res INDEX = 4 LOW = @nodeA HIGH = @inter1 +@nodeA INDEX = 2 LOW = ZERO HIGH = ONE +@inter1 INDEX = 3 LOW = @nodeA HIGH = ONE +*/ + +displayBdd(res,0); + +/* it will display +@res INDEX = 4 LOW = @nodeA HIGH = @inter1 +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR createNodeTermBdd (3), +.BR applyBinBdd (3), +.BR applyBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR addListBdd (3), +.BR notBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/gcNodeBdd.3 b/alliance/src/log/man3/gcNodeBdd.3 new file mode 100644 index 00000000..418ed652 --- /dev/null +++ b/alliance/src/log/man3/gcNodeBdd.3 @@ -0,0 +1,59 @@ +.\" $Id: gcNodeBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)gcNodeBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH GCNODEBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBgcNodeBdd\fP \- does a garbage collection +.SH SYNOPSYS +.nf +#include "logmmm.h" +void gcNodeBdd(pt) +chain_list *pt; +.fi +.SH PARAMETER +.TP 20 +\fIpt\fP +chained list of BDD to rescue +.SH DESCRIPTION +\fBgcNodeBdd()\fP removes all the nodes that aren't used in the BDD pointed in the chained list \fIpt\fP. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res1,res2; +chain_list *ptCL; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); + +res1 = applyBinBdd(OR,applyBinBdd(OR,nodeA,nodeB),nodeC); +res2 = applyBinBdd(AND,applyBinBdd(AND,nodeA,nodeB),nodeC); +printf("number of nodes in memory = %d",numberAllNodeBdd()); + +/* it will display +7 +*/ +ptCL = addchain(NULL,res1); +gcNodeBdd(ptCL); /* only res1 nodes are saved */ + +freechain(ptCL); +printf("number of nodes in memory = %d",numberAllNodeBdd()); + +/* it will display +number of nodes in memory = 5 +*/ +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR markBdd (3), +.BR supportChain_listBdd (3), +.BR markAllBdd (3), +.BR numberNodeBdd (3), + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/initializeBdd.3 b/alliance/src/log/man3/initializeBdd.3 new file mode 100644 index 00000000..aed7b178 --- /dev/null +++ b/alliance/src/log/man3/initializeBdd.3 @@ -0,0 +1,48 @@ +.\" $Id: initializeBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)initializeBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH INITIALIZEBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBinitializeBdd\fP \- initializes the BDDs system +.SH SYNOPSYS +.nf +#include "logmmm.h" +void initializeBdd(size) +int size; +.fi +.SH PARAMETER +.TP 20 +\fIsize\fP +First size of BDD system +.SH DESCRIPTION +\fBinitializeBdd()\fP initializes the BDDs system. \fIsize\fP can be equal to SMALL_BDD, MEDIUM_BDD or LARGE_BDD according to the application size. This function creates the \fIzero\fP and \fIone\fP node that correspond to the 0 and 1 boolean constants. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" + +initializeBdd(MEDIUM_BDD); + +dislayBdd(one); +/* it will display +ONE +*/ + +/* application using BDD ... */ + +destroyBdd(1); +.fi +.SH ERROR +"initializeBdd : error - size out of bound" +.br +\fIsize\fP must be included into \fISMALL_BDD\fP and \fILARGE_BDD\fP. +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR destroyBdd (3), +.BR resetBdd (3), +.BR markAllBdd (3), +.BR numberNodeAllBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/markAllBdd.3 b/alliance/src/log/man3/markAllBdd.3 new file mode 100644 index 00000000..10ed21c0 --- /dev/null +++ b/alliance/src/log/man3/markAllBdd.3 @@ -0,0 +1,28 @@ +.\" $Id: markAllBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)markAllBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH MARKALLBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBmarkAllBdd\fP \- marks all the nodes of the BDDs system +.SH SYNOPSYS +.nf +#include "logmmm.h" +void markAllBdd(value) +short value; +.fi +.SH PARAMETER +.TP 20 +\fIvalue\fP +value to assign +.SH DESCRIPTION +\fBmarkAllBdd()\fP assigns to \fIvalue\fP the marks of all the nodes used in the BDDs system. +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR markBdd (3), +.BR numberNodeBdd (3), +.BR numberNodeAllBdd (3), +.BR supportChain_listBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/markBdd.3 b/alliance/src/log/man3/markBdd.3 new file mode 100644 index 00000000..fce9f817 --- /dev/null +++ b/alliance/src/log/man3/markBdd.3 @@ -0,0 +1,32 @@ +.\" $Id: markBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)markBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH MARKBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBmarkBdd\fP \- marks all nodes of a BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +void markBdd(pBdd,value) +pNode pBdd; +short value; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd\fP +BDD to mark +.TP 20 +\fIvalue\fP +value to assign +.SH DESCRIPTION +\fBmarkBdd()\fP assigns to \fIvalue\fP the field \fImark\fP of all the nodes used in \fIpBdd\fP. This function is used for the garbage collection. When a node is created, its mark is set to 0 (the default value). +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR markAllBdd (3), +.BR numberNodeBdd (3), +.BR numberNodeAllBdd (3), +.BR gcNodeBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/notBdd.3 b/alliance/src/log/man3/notBdd.3 new file mode 100644 index 00000000..a402dff6 --- /dev/null +++ b/alliance/src/log/man3/notBdd.3 @@ -0,0 +1,48 @@ +.\" $Id: notBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)notBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH NOTBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBnotBdd\fP \- complements a BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode notBdd(pBdd) +pNode pBdd; +.fi +.SH PARAMETER +.TP 20 +\fIpBdd\fP +BDD to complement +.SH DESCRIPTION +\fBnotBdd()\fP applies NOT operator to \fIpBdd\fP. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); + +displayBdd(notBdd(nodeA),1); + +/* it will display +@nodeA INDEX = 2 LOW = ONE HIGH = ZERO +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR applyBinBdd (3), +.BR applyBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/numberNodeAllBdd.3 b/alliance/src/log/man3/numberNodeAllBdd.3 new file mode 100644 index 00000000..9e378f0b --- /dev/null +++ b/alliance/src/log/man3/numberNodeAllBdd.3 @@ -0,0 +1,51 @@ +.\" $Id: numberNodeAllBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)numberNodeAllBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH NUMBERNODEALLBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBnumberNodeAllBdd\fP \- count the number of nodes used in the BDD system +.SH SYNOPSYS +.nf +#include "logmmm.h" +int numberNodeAllBdd() +.fi +.SH DESCRIPTION +\fBnumberNodeAllBdd()\fP count the number of the nodes that are used in the BDD system +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; +chain_list *pt; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); +pt = NULL; +pt = addListBdd(pt,nodeA); +pt = addListBdd(pt,nodeB); +pt = addListBdd(pt,nodeC); +res = applyBdd(OR,pt); +printf("number of nodes = %d",numberNodeAllBdd()); + +/* it will display +number of nodes = 5 +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR addListBdd (3), +.BR numberNodeBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/numberNodeBdd.3 b/alliance/src/log/man3/numberNodeBdd.3 new file mode 100644 index 00000000..0c60d892 --- /dev/null +++ b/alliance/src/log/man3/numberNodeBdd.3 @@ -0,0 +1,56 @@ +.\" $Id: numberNodeBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)numberNodeBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH NUMBERNODEBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBnumberNodeBdd\fP \- computes the number of nodes used in a BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +int numberNodeBdd(pBdd) +pNode pBdd; +.fi +.SH PARAMETER +.TP 20 +\fIpBdd\fP +BDD on wich the compute does +.SH DESCRIPTION +\fBnumberNodeBdd()\fP computes the number of reduced nodes that are used in \fIpBdd\fP. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; +chain_list *pt; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); +pt = NULL; +pt = addListBdd(pt,nodeA); +pt = addListBdd(pt,nodeB); +pt = addListBdd(pt,nodeC); +res = applyBdd(XOR,pt); +printf("number of nodes = %d",numberNodeBdd(res)); + +/* it will display +number of nodes = 5 +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR addListBdd (3), +.BR numberNodeBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/resetBdd.3 b/alliance/src/log/man3/resetBdd.3 new file mode 100644 index 00000000..5f87566a --- /dev/null +++ b/alliance/src/log/man3/resetBdd.3 @@ -0,0 +1,39 @@ +.\" $Id: resetBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)resetBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH RESETBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBresetBdd\fP \- resets the BDDs system +.SH SYNOPSYS +.nf +#include "logmmm.h" +void resetBdd() +.fi +.SH DESCRIPTION +\fBresetBdd()\fP resets the BDDs system. This function can be only called after the \fBinitializeBdd()\fP function. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" + +initializeBdd(LARGE_BDD); + +/* first application using BDD ... */ + +resetBdd(); + +/* second application using BDD ... */ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR destroyBdd (3), +.BR gcNodeBdd (3), +.BR markAllBdd (3), +.BR numberNodeAllBdd (3), +.BR resetBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/simplifDcOneBdd.3 b/alliance/src/log/man3/simplifDcOneBdd.3 new file mode 100644 index 00000000..f20bcb5f --- /dev/null +++ b/alliance/src/log/man3/simplifDcOneBdd.3 @@ -0,0 +1,50 @@ +.\" $Id: simplifDcOneBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)simplifDcZeroBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH SIMPLIFDCONEBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBsimplifDcOneBdd\fP \- simplifies a BDD with don't cares on its on-set part +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode simplifDcOneBdd(pBdd1,pBdd2) +pNode pBdd1; +pNode pBdd2; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd1\fP +BDD to simplify +.TP 20 +\fIpBdd2\fP +"don't care" function +.SH DESCRIPTION +\fBsimplifDcOneBdd()\fP simplifies \fIpBdd1\fP with \fIpBdd2\fP. \fIpBdd2\fP must be included imperatively in the on-set part of pBdd1. This function returns a BDD that depends to the order of the BDD. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB; +pNode res,res1,res2; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res1 = applyBinBdd(XOR,nodeA,nodeB); /* res1 = (XOR a b) */ +res2 = applyBinBdd(AND,notBdd(nodeA),nodeB); /* res2 = (AND (not a) b) */ +res = simplifDcOneBdd(res1,res2); /* res1 and res2 = res2 */ + +/* res = (AND a (not b)) */ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR simplifDcZeroBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR upVarBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/simplifDcZeroBdd.3 b/alliance/src/log/man3/simplifDcZeroBdd.3 new file mode 100644 index 00000000..a1240d4d --- /dev/null +++ b/alliance/src/log/man3/simplifDcZeroBdd.3 @@ -0,0 +1,57 @@ +.\" $Id: simplifDcZeroBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)simplifDcZeroBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH SIMPLIFDCZEROBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBsimplifDcZeroBdd\fP \- simplifies a BDD with don't cares on its off-set part +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode simplifDcZeroBdd(pBdd1,pBdd2) +pNode pBdd1; +pNode pBdd2; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd1\fP +BDD to simplify +.TP 20 +\fIpBdd2\fP +"don't care" function +.SH DESCRIPTION +\fBsimplifDcZeroBdd()\fP simplifies \fIpBdd1\fP with \fIpBdd2\fP. \fIpBdd2\fP must be included imperatively in the off-set part of pBdd1. This function returns a BDD that depends to the order of the BDD. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,NodeB; +pNode res,res1,res2; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res1 = applyBinBdd(OR,nodeA,nodeB); /* res1 = (OR a b) */ +res2 = applyBinBdd(NOR,nodeA,nodeB); /* res2 = (NOR a b) */ +res = simplifDcZeroBdd(res1,res2); /* res1 and res2 = 0 */ +displayBdd(res,1); + +/* it will display +@res ONE +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR simplifDcOneBdd (3), +.BR applyBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR applyBinBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/supportChain_listBdd.3 b/alliance/src/log/man3/supportChain_listBdd.3 new file mode 100644 index 00000000..3606db01 --- /dev/null +++ b/alliance/src/log/man3/supportChain_listBdd.3 @@ -0,0 +1,65 @@ +.\" $Id: supportChain_listBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)supportChain_listBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH SUPPORTCHAIN_LISTBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBsupportChain_listBdd\fP \- returns a chained list of nodes that are used in a given BDD. +.SH SYNOPSYS +.nf +#include "logmmm.h" +chain_list *supportChain_listBdd(pBdd) +pNode pBdd; +.fi +.SH PARAMETER +.TP 20 +\fIpBdd\fP +BDD +.SH DESCRIPTION +\fBsupportChain_listBdd()\fP creates a chained list in wich all the nodes of \fIpBdd\fP are represented. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB,nodeC; +pNode res; +chain_list *pt; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +nodeC = createNodeTermBdd(4); +pt = NULL; +pt = addListBdd(pt,nodeA); +pt = addListBdd(pt,nodeB); +pt = addListBdd(pt,nodeC); +res = applyBdd(OR,pt); +pt = supportChain_listBdd(res); + +while (pt) + { + printf("--- "); + displayBdd((pNode) pt->DATA,0); /* displays the node */ + pt = pt->NEXT; + } +/* it will display + +--- @nodeA index = 2 LOW = ZERO HIGH = ONE +--- @inter index = 3 LOW = @nodeA HIGH = ONE +--- @res index = 4 LOW = @inter HIGH = ONE +*/ + +destroyBdd(1); +.fi +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR numberNodeBdd (3), +.BR addListBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/man3/upVarBdd.3 b/alliance/src/log/man3/upVarBdd.3 new file mode 100644 index 00000000..3f4640b2 --- /dev/null +++ b/alliance/src/log/man3/upVarBdd.3 @@ -0,0 +1,64 @@ +.\" $Id: upVarBdd.3,v 1.1 2002/04/03 13:13:26 ludo Exp $ +.\" @(#)upVarBdd.2 7.01 92/08/22 ; Labo masi cao-vlsi; Author : Luc Burgun +.TH UPVARBDD 3 "October 1, 1997" "ASIM/LIP6" "BDD functions" +.so man1/alc_origin.1 +.SH NAME +\fBupVarBdd\fP \- brings up an index in a BDD +.SH SYNOPSYS +.nf +#include "logmmm.h" +pNode upVarBdd(pBdd,oldIndex,newIndex) +pNode pBdd; +short oldIndex,newIndex; +.fi +.SH PARAMETERS +.TP 20 +\fIpBdd\fP +BDD in wich \fIindex\fP is came up +.TP 20 +\fIoldIndex\fP +index to come up +.TP 20 +\fInewIndex\fP +new index +.SH DESCRIPTION +\fBupVarBdd()\fP constructs a graph obtained by bringing up \fIoldIndex\fP to \fInewIndex\fP. This function is called by the BDDs reordering function. +.SH EXAMPLE +.nf +#include "mutnnn.h" /* mbk utilities */ +#include "logmmm.h" +pNode nodeA,nodeB; +pNode res; + +initializeBdd(SMALL_BDD); +nodeA = createNodeTermBdd(3); +nodeB = createNodeTermBdd(3); +res = applyBinBdd(OR,nodeA,nodeB); /* res = (OR a b) +res = upVarBdd(res,2,4); +displayBdd(res,1); + +/* it will display +@res INDEX 4 LOW = @nodeB HIGH = ONE +@nodeB INDEX 3 LOW = ZERO HIGH = ONE +*/ + +destroyBdd(1); +.fi +.SH ERROR +"upVarBdd : error - newIndex <= oldIndex" +.br +The new index must be higher than the old index. +.SH SEE ALSO +.BR log (1), +.BR bdd (1), +.BR applyBdd (3), +.BR notBdd (3), +.BR constraintBdd (3), +.BR composeBdd (3), +.BR applyBinBdd (3), +.BR addListBdd (3), +.BR displayBdd (3), +.BR createNodeTermBdd (3). + +.so man1/alc_bug_report.1 + diff --git a/alliance/src/log/src/Makefile.am b/alliance/src/log/src/Makefile.am new file mode 100644 index 00000000..620bfd62 --- /dev/null +++ b/alliance/src/log/src/Makefile.am @@ -0,0 +1,27 @@ +CFLAGS = @CFLAGS@ \ + -DALLIANCE_TOP=\"${ALLIANCE_TOP}\" +lib_LIBRARIES = libBdd.a +include_HEADERS = bdd.h +libBdd_a_SOURCES = \ +bdd.h bddenv.h bddimply.h bddsimpdc.h \ +bddalloc.c bdderror.c bddlog.c bddsubst.c \ +bddalloc.h bdderror.h bddlog.h bddsubst.h \ +bddapply.c bddexist.c bddmark.c bddsupport.c \ +bddapply.h bddexist.h bddmark.h bddsupport.h \ +bddassoc.c bddexplosion.c bddnode.c bddsweep.c \ +bddassoc.h bddexplosion.h bddnode.h bddsweep.h \ +bddblock.c bddflag.c bddoptimize.c bddsystem.c \ +bddblock.h bddflag.h bddoptimize.h bddsystem.h \ +bddcheck.c bddfraction.c bddreduce.c bddtest.c \ +bddcheck.h bddfraction.h bddreduce.h bddtest.h \ +bddcircuit.c bddfree.c bddref.c bddtransfert.c \ +bddcircuit.h bddfree.h bddref.h bddtransfert.h \ +bddcofactor.c bddgarbage.c bddrelprod.c bdduser.c \ +bddcofactor.h bddgarbage.h bddrelprod.h bdduser.h \ +bddcompose.c bddheath.c bddreorder.c bddvar.c \ +bddcompose.h bddheath.h bddreorder.h bddvar.h \ +bddconvert.c bddhnode.c bddresize.c bddvaraux.c \ +bddconvert.h bddhnode.h bddresize.h bddvaraux.h \ +bdddump.c bddhoper.c bddsatisfy.c \ +bdddump.h bddhoper.h bddsatisfy.h \ +bddenv.c bddimply.c bddsimpdc.c diff --git a/alliance/src/log/src/log.h b/alliance/src/log/src/log.h new file mode 100644 index 00000000..60c33025 --- /dev/null +++ b/alliance/src/log/src/log.h @@ -0,0 +1,424 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + +/* $Id: log.h,v 1.1 2002/04/03 13:13:25 ludo Exp $ */ + +#ifndef LUC_LOG_H +#define LUC_LOG_H + +#undef OR +#undef AND +#undef XOR +#undef NOT +#undef NOR +#undef NAND +#undef NXOR +#undef CONTRAINT +#undef STABLE +#undef RESTRICT +#undef CNST 10 + +#define OR 0 +#define AND 1 +#define XOR 2 +#define NOT 3 +#define NOR 4 +#define NAND 5 +#define NXOR 6 +#define CONTRAINT 7 +#define STABLE 8 +#define RESTRICT 9 +#define CNST 10 + +/* ================================================================== + Gestion de table de hachage Version du 16.07.91 + Les structures de donnees + Burgun L. + ================================================================== */ + + +#define EMPTYTH -1 +#define VIDETH -1 +#define DELETETH -2 + +/*------ les structures pour la table de hachage des entiers -----*/ + +typedef struct elemTH + { + char *key; + int value; + } + *pElemTH; + +/* table de hachage + length est la longueur de la table, + pElemTH le pointeur sur le debut de table, + count le nombre d'elements deja rentres. */ + +typedef struct tableTH + { + int length; + pElemTH pElem; + int count; + } + *pTH; + + +/* ============================================================== + La bibliotheque des Arbres binaires Lisp-like version 23/08/91 + Burgun L. + Structures de donnees + ============================================================== */ + + + +/*----------- Fonctions Lisp-Like de bas-niveau -------------*/ + +#define CDR(expr) (expr->NEXT) +#define CAR(expr) ((chain_list *) expr->DATA) +#define CADR(expr) CAR(CDR(expr)) +#define ATOM(expr) (!expr->NEXT) +#define VALUE_ATOM(expr) (char *) expr->DATA +#define OPER(expr) ((int)(CAR(expr))->DATA) + + + +/* ============================================================== + La bibliotheque des graphes de decision binaires version 06/09/91 + Burgun L. + Structures de donnees + ============================================================== */ + +#undef OUI +#undef NON +#undef TRUE +#undef FALSE +#undef INPUT +#undef OUTPUT +#undef SMALL +#undef MEDIUM +#undef LARGE + +#undef VIDE +#undef DELETE +#undef TABLE_PLEINE +#undef BDDDELETE +#undef BDDTABLE_PLEINE +#undef MAX_SIZE_BDD + +#undef DONTCARE0 +#undef DONTCARE1 +#undef DONTCARE2 + + +#define OUI 1 +#define NON 0 +#define TRUE 1 +#define FALSE 0 +#define INPUT 0 +#define OUTPUT 1 +#define SMALL 999 +#define MEDIUM 9999 +#define LARGE 99999 +#define SMALL_BDD 0 +#define MEDIUM_BDD 1 +#define LARGE_BDD 2 + +#define VIDE -1 +#define DELETE -2 +#define TABLE_PLEINE -3 +#define BDDDELETE (pNode) DELETE +#define BDDTABLE_PLEINE (pNode) TABLE_PLEINE +#define MAX_SIZE_BDD 50000000 /* 50 Mega de noeuds Bdd */ + +#define DONTCARE0 11 +#define DONTCARE1 12 +#define DONTCARE2 13 + + + +/*---------------- structure d'un noeud de BDD -------------------*/ + +typedef struct node + { + struct node *high, *low; /* les noeuds fils */ + short index; /* index de la variable */ + short mark; /* nombre de peres pointant le noeud */ + } + *pNode; + + +/*--------------- La table de hachage pour des BDD ------------ */ + +/* table de hachage qui retourne des pointeurs de BDD + lenTableBdd est la longueur de la table, + pBddT le pointeur sur le debut de table, + compteur le nombre d'elements deja rentres. */ + +typedef struct tableBdd + { + int lenTableBdd; + pNode *pBdd; + int compteur; + } + *pTableBdd; + + + +/*------ les structures pour la table de hachage local -----*/ + +typedef struct vertexLoc + { + pNode high, low, father; + short oper; + } + *pVertexLoc; + +/* table de hachage pour la recuperation d'operation locale. + lenTable est la longueur de la table, + pElemT le pointeur sur le debut de table, + compteur le nombre d'elements deja rentres. */ + +typedef struct tableLoc + { + int lenTabLoc; + pVertexLoc pLoc; + } + *pTableLoc; + +/*------------- structure pour les circuits -------------*/ + +typedef struct circuit + { + pTH pTI; + pTH pTO; + short countI; + char **pNameI; + char *name; + } + *pCircuit; + +#define MAX_PACK 1000 + +/* structure systeme pour la generation de GDB . */ + +struct systemBdd + { + chain_list *lpAT; + pTableBdd pRT; + pNode pAT; + int indiceAT; + pTableLoc pMC; + } +sysBdd; + +pNode one, zero; + +/**************** DECLARATION DES FONCTIONS *******/ + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +/* Prototypes from log_bdd0.c */ + + extern pNode initVertexBdd __P((int index, pNode high, pNode low)); + extern pNode createNodeTermBdd __P((short index)); + extern void initializeBdd __P((int size)); + extern void destroyBdd __P((int level)); + extern void resetBdd __P(()); + extern int numberNodeAllBdd __P(()); + extern int numberNodeBdd __P((pNode pBdd)); + extern int countNode __P((pNode pt)); + extern int countNodeTdg __P((pNode pt)); + extern chain_list * muxAbl __P((pNode high, pNode low, chain_list *a, char **tabName)); + extern chain_list * bddToAbl __P((pNode pt, char **tabName)); + extern void displayBddLoc __P((short level, pNode pt)); + extern void displayBdd __P((pNode pBdd, int level)); + extern void assignNumNodeBdd __P((pNode bdd, pTH vTable, int *pNodeNumber)); + extern void displayGraphicBdd __P((pNode pBdd)); + extern void displayBddName __P((short level, pNode pt, char **TabName)); + extern pNode notBdd __P((pNode pBdd)); + extern pNode applyTerm __P((int oper, short index, pNode pBdd)); + extern pNode applyBinBdd __P((short oper, pNode pBdd1, pNode pBdd2)); + extern pNode applyBdd __P((short oper, chain_list *pt)); + extern pNode cnstBdd __P((pNode pBdd1, pNode pBddGc)); + extern pNode restrictBdd __P((pNode pBdd1, pNode pBddGc)); + extern pNode constraintBdd __P((pNode pBdd1, pNode pBddGc)); + extern pNode simplifDcZeroBdd __P((pNode pGon, pNode pGdc)); + extern pNode simplifPlusDcZeroBdd __P((pNode pGon, pNode pGdc)); + extern pNode simplifDcOneBdd __P((pNode pGon, pNode pGdc)); + extern pNode simplifDcOneFPGABdd __P((pNode pGon, pNode pGdc)); + extern pNode composeBdd __P((pNode pBdd1, pNode pBdd2, int index)); + extern chain_list * addListBdd __P((chain_list *pt, pNode pBdd)); + extern int oneBdd __P((pNode pBdd)); + extern int zeroBdd __P((pNode pBdd)); + extern int equalBdd __P((pNode pBdd1, pNode pBdd2)); + extern void markBdd __P((pNode pBdd, short value)); + extern pNode upVarBdd __P((pNode pF, pNode pFoldIndex, short newIndex)); + extern void markAllBdd __P((short value)); + extern void supportBddInt __P((pNode pt, chain_list **ppCL)); + extern chain_list * supportChain_listBdd __P((pNode pBdd)); + extern pNode initVertexBddAux __P((short index, pNode high, pNode low, struct systemBdd *sysCible)); + extern pNode regenereBdd __P((pNode pBdd, struct systemBdd *sysCible, pTH pTHNode)); + extern void gcNodeBdd __P((chain_list *pt)); + extern void rempTabIndex __P((pNode pt, char *tabIndex)); + extern chain_list * supportIndexBdd __P((pNode pt, int sens)); + + +/* Prototypes from log_bdd1.c */ + + extern pCircuit initializeCct __P((char *name, int nbI, int nbO)); + extern void resetCct __P((pCircuit pC)); + extern void destroyCct __P((pCircuit pC)); + extern pNode searchOutputCct __P((pCircuit pC, char *name)); + extern void addOutputCct __P((pCircuit pC, char *name, pNode pt)); + extern char * searchIndexCct __P((pCircuit pC, short index)); + extern short searchInputCct __P((pCircuit pC, char *name)); + extern short addInputCct __P((pCircuit pC, char *name)); + extern void delInputCct __P((pCircuit pC, char *name)); + extern void displayCct __P((pCircuit pC, int mode)); + extern void composeCct __P((pCircuit pC, char *name, pNode pt)); + extern void constraintCct __P((pCircuit pC, pNode pt)); + extern void proofCct __P((pCircuit pC1, pCircuit pC2)); + extern pNode ablToBddCct __P((pCircuit pC, chain_list *expr)); + extern void cpOrderCct __P((pCircuit CC1, pCircuit CC2)); + extern void upVarCct __P((pCircuit pC, pNode ptOldIndex, short newIndex)); + extern int numberNodeCct __P((pCircuit pC)); + extern int numberNodeTdgCct __P((pCircuit pC)); + extern chain_list * bddToAblCct __P((pCircuit pC, pNode pBdd)); + extern void gcNodeCct __P((pCircuit pC)); + + +/* Prototypes from log_prefbib.c */ + + extern char * gensym_abl __P((char *name, int num)); + extern void ablError __P((chain_list *expr, char *func)); + extern chain_list * createAtom __P((char *name)); + extern chain_list * createExpr __P((short oper)); + extern chain_list * notExpr __P((chain_list *expr)); + extern chain_list * createBinExpr __P((short oper, chain_list *expr1, chain_list *expr2)); + extern void addQExpr __P((chain_list *expr1, chain_list *expr2)); + extern void addHExpr __P((chain_list *expr1, chain_list *expr2)); + extern void freeExpr __P((chain_list *expr)); + extern char * operToChar __P((short oper)); + extern short charToOper __P((char *name)); + extern void displayExprInt __P((chain_list *expr)); + extern void displayExpr __P((chain_list *expr)); + extern void displayInfExpr __P((chain_list *expr)); + extern char * exprToCharInt __P((chain_list *expr, int mode, char *chaine, int *taille)); + extern char * exprToChar __P((chain_list *expr, int mode)); + extern char * identExprInt __P((chain_list *expr, char *chaine, int *taille)); + extern char * identExpr __P((chain_list *expr)); + extern int profExpr __P((chain_list *expr)); + extern int profAOExpr __P((chain_list *expr)); + extern chain_list * mapCarExpr __P((chain_list *(*func)(), short oper, chain_list *expr)); + extern void mapExpr __P((void (*func)(), chain_list *expr)); + extern int anyExpr __P((int (*func)(), chain_list *expr)); + extern int everyExpr __P((int (*func)(), chain_list *expr)); + extern int searchOperExpr __P((chain_list *expr, short oper)); + extern short searchExprLow __P((chain_list *expr, char *name)); + extern int searchExpr __P((chain_list *expr, char *name)); + extern int equalExpr __P((chain_list *expr1, chain_list *expr2)); + extern int equalVarExpr __P((chain_list *expr1, chain_list *expr2)); + extern int lengthExpr __P((chain_list *expr)); + extern int numberOperBinExpr __P((chain_list *expr)); + extern int numberAtomExpr __P((chain_list *expr)); + extern chain_list * copyExpr __P((chain_list *expr)); + extern void substPhyExpr __P((chain_list *expr1, char *name, chain_list *expr2)); + extern chain_list * substExpr __P((chain_list *expr1, char *name, chain_list *expr2)); + extern chain_list * devXorExpr __P((chain_list *expr)); + extern chain_list * devXor2Expr __P((chain_list *expr)); + extern chain_list * flatPolarityExpr __P((chain_list *expr, int signe)); + extern void flatArityExpr __P((chain_list *expr)); + extern void supportChain_listExprInt __P((chain_list *expr, chain_list **ppCL)); + extern chain_list * supportChain_listExpr __P((chain_list *expr)); + extern void supportPtype_listExprInt __P((chain_list *expr, ptype_list **ppCL)); + extern ptype_list * supportPtype_listExpr __P((chain_list *expr)); + extern chain_list * maxExpr __P((chain_list *expr, int (*func)())); + extern chain_list * minExpr __P((chain_list *expr, int (*func)())); + extern void sortExpr __P((chain_list *expr, long (*func)(), int direction)); + extern int funcNormExpr __P((chain_list *expr)); + extern void normExpr __P((chain_list *expr)); + extern void deleteNumExpr __P((chain_list *expr, int i)); + extern chain_list * searchNumExpr __P((chain_list *expr, int i)); + extern int numberOccExpr __P((chain_list *exp, char *name)); + extern void changeOperExpr __P((chain_list *expr, short oper)); + extern chain_list * simplif10Expr __P((chain_list *expr)); + extern chain_list * simplifNotExpr __P((chain_list *exp)); + extern chain_list * charToExprInt __P((char *stringExpr, int *cptCar)); + extern chain_list * charToExpr __P((char *stringExpr)); + extern char * tokenExpr __P((char *stringExpr, int *cptCar)); + extern int PMExprInt __P((chain_list *expr, chain_list *pattern, ptype_list **bind)); + extern int PMExpr __P((chain_list *expr, chain_list *pattern)); + + +/* Prototypes from log_thash.c */ + + extern int hashTH __P((char *pn)); + extern pTH createTH __P((int len)); + extern void destroyTH __P((pTH pTable)); + extern int searchTH __P((pTH pTable, char *key)); + extern int addTH __P((pTH pTable, char *key, int value)); + extern int addExistTH __P((pTH pTable, char *key, int value)); + extern int deleteTH __P((pTH pTable, char *key)); + extern void displayTH __P((pTH pTable)); + extern void reAllocTH __P((pTH pTable)); + + +/* Prototypes from log_thashbdd.c */ + + extern int hashBdd __P((int index, pNode high, pNode low)); + extern int newKeyBdd __P((int index, pNode high, pNode low)); + extern pTableBdd createTableBdd __P((int len)); + extern void destroyTableBdd __P((pTableBdd pTab)); + extern pTableBdd reAllocTableBdd __P((pTableBdd pTab)); + extern pNode searchTableBdd __P((pTableBdd pTab, int index, pNode high, pNode low)); + extern int addTableBdd __P((pTableBdd pTab, pNode pBdd)); + extern int deleteTableBdd __P((pTableBdd pTab, pNode pBdd)); + extern void displayHashBdd __P((pTableBdd pTab)); + + +/* Prototypes from log_thashloc.c */ + + extern int hashLoc __P((pNode high, pNode low)); + extern pTableLoc createTabLoc __P((int len)); + extern void destroyTabLoc __P((pTableLoc pTab)); + extern pNode searchTabLoc __P((pTableLoc pTab, pNode high, pNode low, short oper)); + extern int addTabLoc __P((pTableLoc pTab, pNode high, pNode low, pNode father, short oper)); + extern void displayLoc __P((pTableLoc pTab)); + extern void videTabLoc __P((pTableLoc pTab)); +#endif diff --git a/alliance/src/log/src/log_bdd0.c b/alliance/src/log/src/log_bdd0.c new file mode 100644 index 00000000..85847b48 --- /dev/null +++ b/alliance/src/log/src/log_bdd0.c @@ -0,0 +1,1912 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + +#ident "$Id: log_bdd0.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + +/****************************************************************************/ +/* Produit : librairie BDD - Gestion de BDD */ +/****************************************************************************/ + +#include +#include "mut.h" +#include "log.h" + +#undef NAME_ATOM +#undef MIN_OPER +#undef MAX_OPER +#define MIN_OPER 0 +#define MAX_OPER 7 + +#define NAME_ATOM createAtom(*(tabName + pt->index - 2)) + +/*------------------------------------------------------------------------------ +initVertexBdd :cree un noeud BDD . +------------------------------------------------------- +parametres :index de la variable. + pointeurs sur les noeuds fils. +------------------------------------------------------- +return :pointeur sur le noeud cree. +------------------------------------------------------------------------------*/ + +pNode +initVertexBdd (index, high, low) + int index; + pNode high, low; +{ + pNode pt; + + + if ((pt = searchTableBdd (sysBdd.pRT, index, high, low)) != NULL) + if (pt != BDDTABLE_PLEINE) + return (pt); + else + { + sysBdd.pRT = reAllocTableBdd (sysBdd.pRT); + return (initVertexBdd (index, high, low)); + } + + if (high == low) /* noeud eliminable */ + return (high); + + if (sysBdd.indiceAT == MAX_PACK) + { + sysBdd.pAT = (pNode) mbkalloc (MAX_PACK * sizeof (struct node)); + sysBdd.indiceAT = 1; + sysBdd.lpAT = addchain (sysBdd.lpAT, (void *) sysBdd.pAT); + } + else + { + sysBdd.pAT++; + sysBdd.indiceAT++; + } + + pt = sysBdd.pAT; + pt->index = index; + pt->high = high; + pt->low = low; + pt->mark = 0; + if (index > 1) + if (addTableBdd (sysBdd.pRT, pt) == TABLE_PLEINE) /* table pleine */ + { + sysBdd.pRT = reAllocTableBdd (sysBdd.pRT); + return (initVertexBdd (index, high, low)); + } + return (pt); +} + +/*------------------------------------------------------------------------------ +createNodeTermBdd :cree un noeud variable . +------------------------------------------------------- +parametres :index de la variable. +------------------------------------------------------- +return :pointeur sur le noeud cree. +------------------------------------------------------------------------------*/ + +pNode +createNodeTermBdd (index) + short index; +{ + pNode pt; + + if (index <= 1) + { + printf ("createNodeTermBdd : error index <= 1\n"); + exit (-1); + } + else + { + pt = initVertexBdd (index, one, zero); + return (pt); + } +} + +/*------------------------------------------------------------------------------ +initializeBdd: Initialise le systeme de la boite a outils des BDD. +------------------------------------------------------- +parametres :rien . +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +initializeBdd (size) + int size; +{ + switch (size) + { + case 0: + sysBdd.pRT = createTableBdd (SMALL); + break; + case 1: + sysBdd.pRT = createTableBdd (MEDIUM); + break; + case 2: + sysBdd.pRT = createTableBdd (LARGE); + break; + default: + printf ("initializeBdd : size out of bound\n"); + exit (-1); + } + + sysBdd.pMC = createTabLoc (MEDIUM); + sysBdd.indiceAT = MAX_PACK; + sysBdd.lpAT = NULL; + + zero = initVertexBdd (0, (pNode) 0, (pNode) 1); + one = initVertexBdd (1, (pNode) 0, (pNode) 1); +} + +/*------------------------------------------------------------------------------ +destroyBdd :desalloue le systeme de la boite a outils des BDD. +------------------------------------------------------- +parametres :niveau de desallocation . +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +destroyBdd (level) + int level; +{ + chain_list *pt; + + if (level == 1) + { + pt = sysBdd.lpAT; + while (pt != NULL) /* desallocation des pages de noeuds */ + { + mbkfree ((pNode) pt->DATA); + pt = pt->NEXT; + } + freechain (sysBdd.lpAT); + sysBdd.lpAT = NULL; + } + else + { + freechain (sysBdd.lpAT); + sysBdd.lpAT = NULL; + } + destroyTableBdd (sysBdd.pRT); /* les tables de hachage */ + destroyTabLoc (sysBdd.pMC); +} + +/*------------------------------------------------------------------------------ +resetBdd :vide le systeme de la boite a outils des BDD. +------------------------------------------------------- +parametres :rien +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +resetBdd () +{ + int i; + pNode *pBdd; + chain_list *pt; + + pt = sysBdd.lpAT; + while (pt) /*vide la liste d'allocation par paquet */ + { + mbkfree ((pNode) pt->DATA); + pt = pt->NEXT; + } + freechain (sysBdd.lpAT); + sysBdd.lpAT = NULL; + + videTabLoc (sysBdd.pMC); + + pBdd = (sysBdd.pRT)->pBdd; + for (i = 0; i < sysBdd.pRT->lenTableBdd; i++) /* vide la table de reduction */ + { + *pBdd = NULL; + pBdd++; + } + (sysBdd.pRT)->compteur = 0; + sysBdd.indiceAT = MAX_PACK; + + zero = initVertexBdd (0, (pNode) 0, (pNode) 1); + one = initVertexBdd (1, (pNode) 0, (pNode) 1); +} + +/*------------------------------------------------------------------------------ +numberNodeAllBdd :compte le nombre de noeud utilise dans le systeme. +------------------------------------------------------- +return :le nombre de noeud. +------------------------------------------------------------------------------*/ + +int +numberNodeAllBdd () +{ + return ((sysBdd.pRT)->compteur); +} + +/*------------------------------------------------------------------------------ +numberNodeBdd :compte le nombre de noeud reduits d'un graphe. +------------------------------------------------------- +parametres :un pointeur de Node. +------------------------------------------------------- +return :le nombre de noeud. +------------------------------------------------------------------------------*/ + +int +numberNodeBdd (pBdd) + pNode pBdd; +{ + int val; + + markBdd (pBdd, -1); + markBdd (pBdd, 0); + val = countNode (pBdd); + markBdd (pBdd, 0); + return (val); +} + +/*------------------------------------------------------------------------------ +countNode : calcul du nombre de noeuds BDD +------------------------------------------------------- +parametres : une pNode +------------------------------------------------------- +return : int +------------------------------------------------------------------------------*/ +int +countNode (pt) + pNode pt; +{ + if (pt->index > 1) + { + if (pt->mark == 0) + { + pt->mark = 1; + return (countNode (pt->high) + countNode (pt->low) + 1); + } + } + return (0); +} + +/*------------------------------------------------------------------------------ +countNodeTdg : calcul du nombre de noeuds equivalent TDG sur un BDD +------------------------------------------------------- +parametres : une pNode +------------------------------------------------------- +return : int +------------------------------------------------------------------------------*/ +int +countNodeTdg (pt) + pNode pt; +{ + if (pt->index > 1) + { + if (pt->mark == 0) + { + int val; + pt->mark = 1; + val = countNodeTdg (pt->high) + countNodeTdg (pt->low) + 1; + markBdd (notBdd (pt), 1); + return val; + } + } + return (0); +} + +/*------------------------------------------------------------------------------ +muxAbl : realise le multiplexeur a.H + a'.L +------------------------------------------------------- +parametres : Deux pointeurs de Node et un pointeur de CHAIN_LIST. +------------------------------------------------------- +return :une pointeur de CHAIN_LIST. +------------------------------------------------------------------------------*/ +chain_list * +muxAbl (high, low, a, tabName) + pNode high, low; + chain_list *a; + char **tabName; +{ + pNode pBdd; + chain_list *expr1, *expr2; + +/*--------- multiplexeur terminal ---------*/ + + if (low->index < 2 && high->index < 2) + { + if (low == one) /* not de la variable */ + return (notExpr (a)); + else /* variable directe */ + return (a); + } + +/*--------- multiplexeur semi-terminal ---------*/ + + if (low == one) /* F = (or (not a) H) */ + return (createBinExpr (OR, bddToAbl (high, tabName), notExpr (a))); + + if (low == zero) /* F = (and a H) */ + return (createBinExpr (AND, bddToAbl (high, tabName), a)); + + if (high == one) /* F = (or a L) */ + return (createBinExpr (OR, bddToAbl (low, tabName), a)); + + if (high == zero) /* F = (and (not a) L) */ + return (createBinExpr (AND, bddToAbl (low, tabName), notExpr (a))); + + + pBdd = applyBinBdd (AND, high, low); + + if (pBdd == zero && applyBinBdd (OR, low, high) == one) + + /* (xor a L) */ + { + /* choix L ou H ? */ + + return (createBinExpr (XOR, bddToAbl (low, tabName), a)); + } + + /* H est inclu dans L */ + + if (pBdd == high) + { + + expr2 = createBinExpr (OR, + bddToAbl (high, tabName), + createBinExpr (AND, + bddToAbl (low, tabName), + notExpr (a))); + + return (expr2); + } + + /* L est inclu dans H */ + + if (pBdd == low) + { + + expr2 = createBinExpr (OR, + bddToAbl (low, tabName), + createBinExpr (AND, + bddToAbl (high, tabName), + copyExpr (a))); + + return (expr2); + } + + /* cas general */ + + expr1 = bddToAbl (low, tabName); + expr2 = bddToAbl (high, tabName); + + expr1 = createBinExpr (OR, + createBinExpr (AND, expr1, notExpr (a)), + createBinExpr (AND, expr2, copyExpr (a))); + + return (expr1); +} + +/*------------------------------------------------------------------------------ +bddToAbl :traduit un BDD en ABL d'une maniere simplifie. Cette fonction + recupere des noms de variables que l'on a empile par index + croissant dans une table. +------------------------------------------------------- +parametres :un pointeur de NODE. +------------------------------------------------------- +return :une pointeur de CHAIN_LIST. +------------------------------------------------------------------------------*/ +chain_list * +bddToAbl (pt, tabName) + pNode pt; + char **tabName; +{ + chain_list *expr1; + pNode pBdd; + chain_list *res = NULL; + +/*----------------- noeud ONE ou ZERO ------------------*/ + + if (pt->index < 2) + { + if (pt->index == 0) + res = createAtom ("'0'"); + else + res = createAtom ("'1'"); + return (res); + } + +/*----------------- variable terminale -----------------*/ + + if ((pt->low)->index < 2 || (pt->high)->index < 2) + { + if ((pt->low)->index < 2 && (pt->high)->index < 2) + { + if (pt->low == one) /* not de la variable */ + res = notExpr (NAME_ATOM); + else /* variable directe */ + res = NAME_ATOM; + } + else + /* variable semi-terminale */ + { + if (pt->low == one) /* F = (or (not a) H) */ + res = createBinExpr (OR, bddToAbl (pt->high, tabName), notExpr (NAME_ATOM)); + + if (pt->low == zero) /* F = (and a H) */ + res = createBinExpr (AND, bddToAbl (pt->high, tabName), NAME_ATOM); + + if (pt->high == one) /* F = (or a L) */ + res = createBinExpr (OR, bddToAbl (pt->low, tabName), NAME_ATOM); + + if (pt->high == zero) /* F = (and (not a) L) */ + res = createBinExpr (AND, bddToAbl (pt->low, tabName), notExpr (NAME_ATOM)); + } + return (res); + } + else + { + +/*---------------- variable non-terminale ----------------*/ + + /* recherche de noyaux non-atomique pour le multiplexeur */ + + /* noyaux a double polarite */ + + if (pt->high == (pt->low)->high || pt->high == (pt->low)->low) + { + expr1 = createExpr (OR); + pBdd = pt; /* sauvegarde de pt */ + while (pt->high == pBdd->high || pt->low == pBdd->high) + { + if (pt->high == pBdd->high) + { + addQExpr (expr1, NAME_ATOM); + pt = pt->low; + } + else + { + addQExpr (expr1, notExpr (NAME_ATOM)); + pt = pt->high; + } + } + res = muxAbl (pBdd->high, pt, expr1, tabName); + pt = pBdd; + return (res); + } + else + { + if (pt->low == (pt->high)->low || pt->low == (pt->high)->high) + { + expr1 = createExpr (AND); + pBdd = pt; /* sauvegarde de pt */ + while (pt->low == pBdd->low || pt->high == pBdd->low) + { + if (pt->low == pBdd->low) + { + addQExpr (expr1, NAME_ATOM); + pt = pt->high; + } + else + { + addQExpr (expr1, notExpr (NAME_ATOM)); + pt = pt->low; + } + } + res = muxAbl (pt, pBdd->low, expr1, tabName); + pt = pBdd; + return (res); + } + else + { + + /* noyaux XOR-NXOR */ + + if ((pt->high)->high == (pt->low)->low && + (pt->high)->low == (pt->low)->high && + (pt->high)->index == (pt->low)->index) + { + expr1 = createExpr (XOR); + addQExpr (expr1, NAME_ATOM); + pBdd = pt; + pt = pt->low; + addQExpr (expr1, NAME_ATOM); + pt = pBdd; + + res = muxAbl ((pt->low)->high, (pt->low)->low, expr1, tabName); + return (res); + } + } + } + /* (or (and a H) (and (not a) L) */ + + expr1 = muxAbl (pt->high, pt->low, NAME_ATOM, tabName); + + return (expr1); + } +} + +/*------------------------------------------------------------------------------ +displayBdd : visualise le BDD . +------------------------------------------------------- +parametres :niveau d'affichage ,pointeur sur le noeud tete de graphe. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +displayBddLoc (level, pt) + short level; + pNode pt; +{ + + if (pt->mark == 1) + return; + if (pt->index > 1) + pt->mark = 1; + if (pt->index > 1) + { + printf ("%d\t INDEX = %d\t", (int) pt, (int) pt->index); + + if ((pt->low)->index == 0) + printf (" LOW = ZERO"); + else if ((pt->low)->index == 1) + printf (" LOW = ONE"); + else + printf (" LOW = %d", (int) pt->low); + + if ((pt->high)->index == 0) + printf ("\t HIGH = ZERO\n"); + else if ((pt->high)->index == 1) + printf ("\t HIGH = ONE\n"); + else + printf ("\t HIGH = %d\n", (int) pt->high); + + /* appel recursif */ + + if (level == 1) + { + if ((pt->low)->index > 1) + displayBddLoc (level, pt->low); + if ((pt->high)->index > 1) + displayBddLoc (level, pt->high); + } + } + else if (pt->index == 1) + printf ("ONE INDEX = 1\n"); + else + printf ("ZERO INDEX = 0\n"); +} + +void +displayBdd (pBdd, level) + pNode pBdd; + int level; +{ + markBdd (pBdd, 0); + displayBddLoc (level, pBdd); + markBdd (pBdd, 0); +} + +/*---------------------------------------------------------------------------- +assignNumNodeBdd : assigns with an integer each vertex in a Hash Table +------------------------------------------------------------------------------ +return : nothing +------------------------------------------------------------------------------*/ + +void +assignNumNodeBdd (bdd, vTable, pNodeNumber) + pNode bdd; + pTH vTable; + int *pNodeNumber; +{ + if (bdd != one && bdd != zero) + { + if (searchTH (vTable, (char *) bdd) == EMPTYTH || searchTH (vTable, (char *) bdd) == DELETETH) + { + addTH (vTable, (char *)bdd, *pNodeNumber); + *pNodeNumber = *pNodeNumber + 1; + } + + assignNumNodeBdd (bdd->low, vTable, pNodeNumber); + assignNumNodeBdd (bdd->high, vTable, pNodeNumber); + } + else + { + if (bdd == one) + { + addTH (vTable, (char *)bdd, 1); + } + else + addTH (vTable, (char *)bdd, 0); + } +} +/*------------------------------------------------------------------------------ +displayGraphicBDD : visualise le BDD . +------------------------------------------------------- +parametres : pointeur sur le noeud tete de graphe. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +displayGraphicBdd (pBdd) + pNode pBdd; +{ + pTH vTable; + int numNode = 2; + chain_list *lst, *supp; + int i; + + supp = reverse (supportChain_listBdd (pBdd)); + + /* on refait la numerotation */ + + vTable = createTH (100); + + addTH (vTable, (char *)zero, 0); + addTH (vTable, (char *)one, 1); + for (i = pBdd->index; i > 1; i--) + { + lst = supp; + while (lst) + { + pNode pt = (pNode) lst->DATA; + if (i == pt->index) + { + addTH (vTable, (char *)pt, numNode); + numNode++; + } + lst = lst->NEXT; + } + } + + + printf ("\n"); + printf ("INDEX | ROBDD\n"); + printf ("=========================================================================\n"); + printf (" |\n"); + + for (i = pBdd->index; i > 1; i--) + { + if (i < 10) + printf (" %d | ", i); + else + printf (" %d | ", i); + lst = supp; + while (lst) + { + pNode pt = (pNode) lst->DATA; + + if (i == pt->index) + { + int numLow = searchTH (vTable, (char *) pt->low); + int numHigh = searchTH (vTable, (char *) pt->high); + int num = searchTH (vTable, (char *)pt); + + printf (" %d_(%d)_%d ", numLow, num, numHigh); + } + lst = lst->NEXT; + } + printf ("\n"); + printf (" |\n"); + } + printf ("=========================================================================\n"); + destroyTH (vTable); +} + +/*------------------------------------------------------------------------------ +displayBddName :visualise le BDD en substituant l'index par son nom INPUT . +------------------------------------------------------- +parametres :niveau d'affichage ,pointeur sur le noeud tete de graphe et le + le pointeur de table de Name. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +displayBddName (level, pt, TabName) + short level; + pNode pt; + char **TabName; +{ + + if (pt->mark == 1) + return; + pt->mark = 1; + if (pt->index > 1) + { + printf ("%d\t INPUT = %s\t", (int) pt, *(TabName + pt->index - 2)); + if ((pt->high)->index == 0) + printf (" HIGH = ZERO"); + else if ((pt->high)->index == 1) + printf (" HIGH = ONE"); + else + printf (" HIGH = %d", (int) pt->high); + + if ((pt->low)->index == 0) + printf ("\t LOW = ZERO\n"); + else if ((pt->low)->index == 1) + printf ("\t LOW = ONE\n"); + else + printf ("\t LOW = %d\n", (int) pt->low); + if (level == 1) + { + if ((pt->low)->index > 1) + displayBddName (level, pt->low, TabName); + if ((pt->high)->index > 1) + displayBddName (level, pt->high, TabName); + } + } + else if (pt->index == 1) + printf ("ONE INDEX = 1\n"); + else + printf ("ZERO INDEX = 0\n"); +} + +/*------------------------------------------------------------------------------ +notBdd :inversion d'un arbre Bdd. +------------------------------------------------------- +parametres :un pointeur de Bdd. +------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +notBdd (pBdd) + pNode pBdd; +{ + pNode pBddLoc; + + if (pBdd == zero) + return (one); + if (pBdd == one) + return (zero); + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd, pBdd, NOT); + if (pBddLoc != NULL) + return (pBddLoc); + pBddLoc = initVertexBdd (pBdd->index, notBdd (pBdd->high), notBdd (pBdd->low)); + addTabLoc (sysBdd.pMC, pBdd, pBdd, pBddLoc, NOT); + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +applyTerm :application d'un operateur sur un Bdd avec un noeud terminal. +------------------------------------------------------- +parametres :un operateur,un index de noeud terminal,un pointeur de Bdd. +------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +applyTerm (oper, index, pBdd) + int oper; + short index; + pNode pBdd; +{ + /* noeud one */ + + if (index == 1) + if (oper == OR) + return (one); + else if (oper == NAND || oper == XOR) + return (notBdd (pBdd)); + else if (oper == AND || oper == NXOR) + return (pBdd); + else + return (zero); + + /* noeud zero */ + + if (oper == AND) + return (zero); + else if (oper == NOR || oper == NXOR) + return (notBdd (pBdd)); + else if (oper == OR || oper == XOR) + return (pBdd); + else + return (one); /* c'est un "nand" */ +} + + +/*------------------------------------------------------------------------------ +applyBinBdd :application d'un operateur sur deux Bdd. +------------------------------------------------------- +parametres :un operateur,deux pointeurs de Bdd. +------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +applyBinBdd (oper, pBdd1, pBdd2) + short oper; + pNode pBdd1, pBdd2; +{ + + pNode pBddLoc; + short index1 = pBdd1->index; + short index2 = pBdd2->index; + + if ((index1 < 2) || (index2 < 2)) /* il existe un noeud terminal */ + if ((index1 < 2) && (index2 < 2)) /* tous les deux sont terminaux */ + + if (index1 != index2) /* 01 ou 10 */ + if (oper == OR || oper == NAND || oper == XOR) + return (one); + else + return (zero); + else if (index1 == 0) /* 00 */ + if (oper == NOR || oper == NAND || oper == NXOR) + return (one); + else + return (zero); + else + /* 11 */ if (oper == OR || oper == AND || oper == NXOR) + return (one); + else + return (zero); + else if (index1 < 2) + return (applyTerm (oper, index1, pBdd2)); + else + return (applyTerm (oper, index2, pBdd1)); + + /* les index ne correspondent pas a des noeuds terminaux */ + + + /* recherche dans la table de hachage locale */ + + if (pBdd1 > pBdd2) + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd1, pBdd2, oper); + else + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd2, pBdd1, oper); + + /* operation deja calcule... */ + + if (pBddLoc != NULL) + return (pBddLoc); + + + if (index1 == index2) /* deux noeuds de meme index */ + { + if (pBdd1 == pBdd2) /* egalite des pointeurs ==> simplification */ + { + if (oper == OR || oper == AND) + return (pBdd1); + if (oper == NOR || oper == NAND) + return (notBdd (pBdd1)); + if (oper == XOR) + return (zero); + else + return (one); + } + pBddLoc = initVertexBdd (index1, applyBinBdd (oper, pBdd1->high, pBdd2->high), + applyBinBdd (oper, pBdd1->low, pBdd2->low)); + } + else if (index1 < index2) /* deux noeuds d'index different */ + pBddLoc = initVertexBdd (index2, applyBinBdd (oper, pBdd1, pBdd2->high), + applyBinBdd (oper, pBdd1, pBdd2->low)); + else + pBddLoc = initVertexBdd (index1, applyBinBdd (oper, pBdd1->high, pBdd2), + applyBinBdd (oper, pBdd1->low, pBdd2)); + + /* ajout d'un noeud dans la table de hash locale */ + + if (pBdd1 > pBdd2) + addTabLoc (sysBdd.pMC, pBdd1, pBdd2, pBddLoc, oper); + else + addTabLoc (sysBdd.pMC, pBdd2, pBdd1, pBddLoc, oper); + + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +applyBdd :application d'un operateur sur une liste de Bdd. +------------------------------------------------------- +parametres :un operateur,un pointeur de liste de Bdd. +------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +applyBdd (oper, pt) + short oper; + chain_list *pt; +{ + short operateur_N = 0; + pNode pBdd; + pNode pBddResul, pBddInter; + + if (oper > MAX_OPER || oper < MIN_OPER) + { + printf ("applyBdd : error - unknown operator %d\n", oper); + exit (-1); + } + if (pt == NULL) + { + printf ("applyBdd : error chained list is empty\n"); + exit (-1); + } + + pBdd = (pNode) pt->DATA; + + if (pt->NEXT == NULL) /* operateur unaire NOT */ + { + if (oper != NOT) + { + printf ("applyBdd : error - bad operator %s\n", operToChar (oper)); + exit (-1); + } + return (notBdd (pBdd)); + } + + + if ((pt->NEXT)->NEXT == NULL) /* operateur binaire */ + { + pBddResul = applyBinBdd (oper, pBdd, (pNode) (pt->NEXT)->DATA); + return (pBddResul); + } + + /* operateur negatif d'arite superieure a trois */ + + if (oper == NXOR || oper == NAND || oper == NOR) + { + operateur_N = 1; + if (oper == NOR) + oper = OR; + else if (oper == NXOR) + oper = XOR; + else + oper = AND; + } + + pBddInter = applyBdd (oper, pt->NEXT); + pBddResul = applyBinBdd (oper, pBdd, pBddInter); + + if (operateur_N == 1) + return (notBdd (pBddResul)); + else + return (pBddResul); +} +/*---------------------------------------------------------------------------- +cnstBdd :constrainte d'un graphe sur un autre. +------------------------------------------------------------------------------ +parametres :deux graphes Bdd. +----------------------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ +pNode +cnstBdd (pBdd1, pBddGc) + pNode pBdd1, pBddGc; +{ + short index1 = pBdd1->index; + short indexGc = pBddGc->index; + pNode pBddLoc; + + if (indexGc == 1) + return (pBdd1); + + if (index1 < 2) + return (pBdd1); + + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd1, pBddGc, CNST); + if (pBddLoc != NULL) + return (pBddLoc); + + if (index1 == indexGc) + { + if (pBddGc->high == zero) + pBddLoc = cnstBdd (pBdd1->low, pBddGc->low); + else if (pBddGc->low == zero) + pBddLoc = cnstBdd (pBdd1->high, pBddGc->high); + else + pBddLoc = initVertexBdd (indexGc, + cnstBdd (pBdd1->high, pBddGc->high), + cnstBdd (pBdd1->low, pBddGc->low)); + } + else if (index1 < indexGc) + pBddLoc = initVertexBdd (indexGc, cnstBdd (pBdd1, pBddGc->high), + cnstBdd (pBdd1, pBddGc->low)); + else + pBddLoc = initVertexBdd (index1, cnstBdd (pBdd1->high, pBddGc), + cnstBdd (pBdd1->low, pBddGc)); + addTabLoc (sysBdd.pMC, pBdd1, pBddGc, pBddLoc, CNST); + return (pBddLoc); +} + +/*---------------------------------------------------------------------------- +restrictBdd :constrainte d'un graphe sur un autre. +------------------------------------------------------------------------------ +parametres :deux graphes Bdd. +----------------------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +restrictBdd (pBdd1, pBddGc) + pNode pBdd1, pBddGc; +{ + short index1 = pBdd1->index; + short indexGc = pBddGc->index; + pNode pBddLoc; + + if (indexGc == 1) + return (pBdd1); + + if (index1 < 2) + return (pBdd1); + + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd1, pBddGc, RESTRICT); + if (pBddLoc != NULL) + return (pBddLoc); + + if (index1 == indexGc) + { + if (pBddGc->high == zero) + pBddLoc = restrictBdd (pBdd1->low, pBddGc->low); + else if (pBddGc->low == zero) + pBddLoc = restrictBdd (pBdd1->high, pBddGc->high); + else + pBddLoc = initVertexBdd (indexGc, + restrictBdd (pBdd1->high, pBddGc->high), + restrictBdd (pBdd1->low, pBddGc->low)); + } + else if (index1 < indexGc) + pBddLoc = restrictBdd (pBdd1, applyBinBdd (OR, pBddGc->low, pBddGc->high)); + else + pBddLoc = initVertexBdd (index1, restrictBdd (pBdd1->high, pBddGc), + restrictBdd (pBdd1->low, pBddGc)); + addTabLoc (sysBdd.pMC, pBdd1, pBddGc, pBddLoc, RESTRICT); + return (pBddLoc); +} + +/*---------------------------------------------------------------------------- +constraintBdd :constrainte d'un graphe sur un autre. +------------------------------------------------------------------------------ +parametres :deux graphes Bdd. +----------------------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +constraintBdd (pBdd1, pBddGc) + pNode pBdd1, pBddGc; +{ + short index1 = pBdd1->index; + short indexGc = pBddGc->index; + pNode pBddLoc; + + if (index1 == 0) + return (zero); + if (index1 == 1) + return (one); + if (indexGc == 1) + return (pBdd1); + + if (pBdd1 == pBddGc) + return (one); /* pBdd1 = pBddGc ==> ONE */ + + pBddLoc = searchTabLoc (sysBdd.pMC, pBdd1, pBddGc, CONTRAINT); + if (pBddLoc != NULL) + return (pBddLoc); + + if (index1 == indexGc) + { + if (pBddGc->high == zero) + pBddLoc = constraintBdd (pBdd1->low, pBddGc->low); + else if (pBddGc->low == zero) + pBddLoc = constraintBdd (pBdd1->high, pBddGc->high); + else + pBddLoc = initVertexBdd (indexGc, + constraintBdd (pBdd1->high, pBddGc->high), + constraintBdd (pBdd1->low, pBddGc->low)); + } + else if (index1 < indexGc) + pBddLoc = initVertexBdd (indexGc, constraintBdd (pBdd1, pBddGc->high), + constraintBdd (pBdd1, pBddGc->low)); + else + pBddLoc = initVertexBdd (index1, constraintBdd (pBdd1->high, pBddGc), + constraintBdd (pBdd1->low, pBddGc)); + addTabLoc (sysBdd.pMC, pBdd1, pBddGc, pBddLoc, CONTRAINT); + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +simplifDcZeroBdd :simplifie un BDD avec un BDD correspondant a un Don't Care. + pGdc est inclu dans pGon'; +------------------------------------------------------- +parametres :deux pointeurs de NODE. +------------------------------------------------------- +return :un pointeur de NODE. +------------------------------------------------------------------------------*/ +pNode +simplifDcZeroBdd (pGon, pGdc) + pNode pGon, pGdc; +{ + pNode pBddLoc; + pNode pAOH, pAOL; + + /* simplification terminale */ + + if (pGdc == zero) + return (pGon); + if (pGon->index < 2) + return (pGon); + + pBddLoc = searchTabLoc (sysBdd.pMC, pGon, pGdc, DONTCARE0); + if (pBddLoc != NULL) + return (pBddLoc); + + /* noeuds de meme index */ + + if (pGdc->index == pGon->index) + { + /* simplification terminales sur les fils */ + + if (pGdc->high == one) + return (simplifDcZeroBdd (pGon->low, pGdc->low)); + if (pGdc->low == one) + return (simplifDcZeroBdd (pGon->high, pGdc->high)); + + /* assignation a une tautologie */ + +/* + if (applyBinBdd(OR,pGon,pGdc) == one) return(one); + */ + + /* elimination du noeud racine de pGon par inclusion */ + + if (pGon->high == zero && applyBinBdd (AND, pGon->low, pGdc->high) == pGon->low) + return (pGon->low); + + if (pGon->low == zero && applyBinBdd (AND, pGon->high, pGdc->low) == pGon->high) + return (pGon->high); + + pAOH = applyBinBdd (AND, pGon->high, applyBinBdd (OR, pGon->low, pGdc->low)); + pAOL = applyBinBdd (AND, pGon->low, applyBinBdd (OR, pGon->high, pGdc->high)); + + if (pAOH == pGon->high && pAOL == pGon->low) + { + pBddLoc = simplifDcZeroBdd (applyBinBdd (OR, pGon->low, pGon->high), + applyBinBdd (AND, pGdc->low, pGdc->high)); + } + else + { + /* cas general */ + + pBddLoc = initVertexBdd (pGon->index, + simplifDcZeroBdd (pGon->high, pGdc->high), + simplifDcZeroBdd (pGon->low, pGdc->low)); + + } + } + else + /* index differents */ + + if (pGon->index > pGdc->index) + pBddLoc = initVertexBdd (pGon->index, simplifDcZeroBdd (pGon->high, pGdc), + simplifDcZeroBdd (pGon->low, pGdc)); + else + pBddLoc = simplifDcZeroBdd (pGon, applyBinBdd (AND, pGdc->low, pGdc->high)); + + addTabLoc (sysBdd.pMC, pGon, pGdc, pBddLoc, DONTCARE0); + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +simplifPlusDcZeroBdd + :simplifie plus fortement un BDD avec un BDD correspondant + a un Don't Care, pGdc est inclu dans pGon'; +------------------------------------------------------- +parametres :deux pointeurs de NODE. +------------------------------------------------------- +return :un pointeur de NODE. +------------------------------------------------------------------------------*/ +pNode +simplifPlusDcZeroBdd (pGon, pGdc) + pNode pGon, pGdc; +{ + pNode pBddLoc; + pNode pAOH, pAOL; + + /* simplification terminale */ + + if (pGdc == zero) + return (pGon); + if (pGdc == one) + return (one); + if (pGon == zero) + return (zero); + + pBddLoc = searchTabLoc (sysBdd.pMC, pGon, pGdc, DONTCARE2); + if (pBddLoc != NULL) + return (pBddLoc); + + /* noeuds de meme index */ + + if (pGdc->index == pGon->index) + { + /* simplification terminales sur les fils */ + + if (pGdc->high == one) + return (simplifPlusDcZeroBdd (pGon->low, pGdc->low)); + if (pGdc->low == one) + return (simplifPlusDcZeroBdd (pGon->high, pGdc->high)); + +/* + if (applyBinBdd(OR,pGon,pGdc) == one) return(one); + */ + + if (pGon->high == zero && applyBinBdd (AND, pGon->low, pGdc->high) == pGon->low) + return (pGon->low); + + if (pGon->low == zero && applyBinBdd (AND, pGon->high, pGdc->low) == pGon->high) + return (pGon->high); + + pAOH = applyBinBdd (AND, pGon->high, applyBinBdd (OR, pGon->low, pGdc->low)); + pAOL = applyBinBdd (AND, pGon->low, applyBinBdd (OR, pGon->high, pGdc->high)); + + if (pAOH == pGon->high && pAOL == pGon->low) + { + pBddLoc = simplifPlusDcZeroBdd (applyBinBdd (OR, pGon->low, pGon->high), + applyBinBdd (AND, pGdc->low, pGdc->high)); + } + else + { + if (pAOL == pGon->low) /* Lon inclu dans Hon+Hdc */ + { /* on maintient la propriete d'inclusion */ + pNode HonRes; + + HonRes = simplifPlusDcZeroBdd ( + applyBinBdd (OR, pGon->low, pGon->high), + applyBinBdd (AND, pGdc->high, notBdd (pGon->low))); + pBddLoc = initVertexBdd (pGon->index, HonRes, + simplifPlusDcZeroBdd (pGon->low, + applyBinBdd (AND, pGdc->low, HonRes))); + } + else + { + if (pAOH == pGon->high) /* Hon inclu dans Lon+Ldc */ + { /* on maintient la propriete d'inclusion */ + pNode LonRes; + + LonRes = simplifPlusDcZeroBdd ( + applyBinBdd (OR, pGon->low, pGon->high), + applyBinBdd (AND, pGdc->low, notBdd (pGon->high))); + pBddLoc = initVertexBdd (pGon->index, + simplifPlusDcZeroBdd (pGon->high, + applyBinBdd (AND, pGdc->high, LonRes)), + LonRes); + } + else + { + + /* cas general */ + + pBddLoc = initVertexBdd (pGon->index, + simplifPlusDcZeroBdd (pGon->high, pGdc->high), + simplifPlusDcZeroBdd (pGon->low, pGdc->low)); + + } + } + } + } + else + /* index differents */ + + if (pGon->index > pGdc->index) + pBddLoc = initVertexBdd (pGon->index, simplifPlusDcZeroBdd (pGon->high, pGdc), + simplifPlusDcZeroBdd (pGon->low, pGdc)); + else + pBddLoc = simplifPlusDcZeroBdd (pGon, applyBinBdd (AND, pGdc->low, pGdc->high)); + + addTabLoc (sysBdd.pMC, pGon, pGdc, pBddLoc, DONTCARE2); + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +simplifDcOneBdd :simplifie un BDD avec un BDD correspondant a un Don't Care. + pGdc est inclu dans pGon; +------------------------------------------------------- +parametres :deux pointeurs de NODE. +------------------------------------------------------- +return :un pointeur de NODE. +------------------------------------------------------------------------------*/ +pNode +simplifDcOneBdd (pGon, pGdc) + pNode pGon, pGdc; +{ + pNode pBddLoc, ptEtOn; + + /* simplification terminale */ + + if (pGdc == zero) + return (pGon); + if (pGon == pGdc) + return (zero); + if (pGon->index < 2) + return (pGon); + + pBddLoc = searchTabLoc (sysBdd.pMC, pGon, pGdc, DONTCARE1); + if (pBddLoc != NULL) + return (pBddLoc); + + /* noeuds de meme index */ + + if (pGdc->index == pGon->index) + { + /* simplification terminales sur les fils */ + + if (pGdc->high == one) + return (simplifDcOneBdd (pGon->low, pGdc->low)); + if (pGdc->low == one) + return (simplifDcOneBdd (pGon->high, pGdc->high)); + + if (pGon->high == one && + applyBinBdd (AND, notBdd (pGdc->high), pGon->low) == notBdd (pGdc->high)) + return (simplifDcOneBdd (pGon->low, applyBinBdd (AND, pGdc->high, pGdc->low))); + + if (pGon->low == one && + applyBinBdd (AND, pGon->high, notBdd (pGdc->low)) == notBdd (pGdc->low)) + return (simplifDcOneBdd (pGon->high, applyBinBdd (AND, pGdc->high, pGdc->low))); + + ptEtOn = applyBinBdd (AND, pGon->high, pGon->low); + + if (applyBinBdd (AND, ptEtOn, notBdd (pGdc->low)) == + applyBinBdd (AND, pGon->low, notBdd (pGdc->low)) && + applyBinBdd (AND, ptEtOn, notBdd (pGdc->high)) == + applyBinBdd (AND, pGon->high, notBdd (pGdc->high))) + { + pBddLoc = simplifDcOneBdd (ptEtOn, applyBinBdd (AND, pGdc->low, pGdc->high)); + } + else + /* cas general */ + + pBddLoc = initVertexBdd (pGon->index, simplifDcOneBdd (pGon->high, pGdc->high), + simplifDcOneBdd (pGon->low, pGdc->low)); + } + else + /* index differents */ + + if (pGon->index > pGdc->index) + pBddLoc = initVertexBdd (pGon->index, simplifDcOneBdd (pGon->high, pGdc), + simplifDcOneBdd (pGon->low, pGdc)); + else + pBddLoc = simplifDcOneBdd (pGon, applyBinBdd (AND, pGdc->low, pGdc->high)); + + addTabLoc (sysBdd.pMC, pGon, pGdc, pBddLoc, DONTCARE1); + return (pBddLoc); +} + +/*------------------------------------------------------------------------------ +simplifDcOneFPGABdd :simplifie un BDD avec un BDD correspondant a un Don't Care. + pGdc est inclu dans pGon; +------------------------------------------------------- +parametres :deux pointeurs de NODE. +------------------------------------------------------- +return :un pointeur de NODE. +------------------------------------------------------------------------------*/ +pNode +simplifDcOneFPGABdd (pGon, pGdc) + pNode pGon, pGdc; +{ + pNode pBddLoc; + + /* simplification terminale */ + + if (pGdc == zero) + return (pGon); + if (pGon == pGdc) + return (zero); + if (pGon->index < 2) + return (pGon); + + pBddLoc = searchTabLoc (sysBdd.pMC, pGon, pGdc, DONTCARE1); + if (pBddLoc != NULL) + return (pBddLoc); + + /* noeuds de meme index */ + + if (pGdc->index == pGon->index) + { + /* simplification terminales sur les fils */ + + if (pGdc->high == one) + return (simplifDcOneFPGABdd (pGon->low, pGdc->low)); + if (pGdc->low == one) + return (simplifDcOneFPGABdd (pGon->high, pGdc->high)); + + if (pGon->high == one && + applyBinBdd (AND, notBdd (pGdc->high), pGon->low) == notBdd (pGdc->high)) + return (simplifDcOneFPGABdd (pGon->low, applyBinBdd (AND, pGdc->high, pGdc->low))); + + if (pGon->low == one && + applyBinBdd (AND, pGon->high, notBdd (pGdc->low)) == notBdd (pGdc->low)) + return (simplifDcOneFPGABdd (pGon->high, applyBinBdd (AND, pGdc->high, pGdc->low))); + + /* cas general */ + + pBddLoc = initVertexBdd (pGon->index, simplifDcOneFPGABdd (pGon->high, pGdc->high), + simplifDcOneFPGABdd (pGon->low, pGdc->low)); + } + else + /* index differents */ + + if (pGon->index > pGdc->index) + pBddLoc = initVertexBdd (pGon->index, simplifDcOneFPGABdd (pGon->high, pGdc), + simplifDcOneFPGABdd (pGon->low, pGdc)); + else + pBddLoc = simplifDcOneFPGABdd (pGon, applyBinBdd (AND, pGdc->low, pGdc->high)); + + addTabLoc (sysBdd.pMC, pGon, pGdc, pBddLoc, DONTCARE1); + return (pBddLoc); +} + +/*---------------------------------------------------------------------------- +composeBdd :Composition de deux graphes +------------------------------------------------------------------------------ +soient index l'index de la variable de decomposition, + G1 le graphe BDD a recalculer et G2 le graphe de V + +on calcule G = G1(V(index)=0).not(G2(V)) + G1(V(index)=1).G2(V) +----------------------------------------------------------------------- +parametres :un operateur,un pointeur de liste de Bdd. +----------------------------------------------------------------------- +return :un pointeur de Bdd. +------------------------------------------------------------------------------*/ + +pNode +composeBdd (pBdd1, pBdd2, index) + pNode pBdd1, pBdd2; + int index; +{ + pNode r1, r2, resul; + + r1 = constraintBdd (pBdd1, initVertexBdd (index, one, zero)); + + if (r1 == pBdd1) /* V n'apparaissait pas dans pBdd1 */ + return (pBdd1); + + r2 = constraintBdd (pBdd1, initVertexBdd (index, zero, one)); + + resul = applyBinBdd (OR, applyBinBdd (AND, pBdd2, r1), + applyBinBdd (AND, notBdd (pBdd2), r2)); + + return (resul); +} + +/*------------------------------------------------------------------------------ +addListBdd : ajoute un nouveau noeud dans la liste des noeuds. +------------------------------------------------------- +parametres : pointeur sur le debut de la liste. +------------------------------------------------------- +return : nouveau pointeur debut de la liste. +------------------------------------------------------------------------------*/ + +chain_list * +addListBdd (pt, pBdd) + chain_list *pt; + pNode pBdd; +{ + chain_list *new_lstGdb, *pCur, *pCurSup; + int index; + + + index = pBdd->index; + + new_lstGdb = addchain (NULL, (void *) pBdd); + + /* l'insertion par index decroissant */ + + if (pt == NULL) + return (new_lstGdb); + + pCur = pt; + pCurSup = pCur; + while (pCur->NEXT != NULL && index < ((pNode) (pCur->NEXT)->DATA)->index) + { + pCurSup = pCur; + pCur = pCur->NEXT; + } + + if (index < ((pNode) pCur->DATA)->index) /* ajout apres */ + { + new_lstGdb->NEXT = pCur->NEXT; + pCur->NEXT = new_lstGdb; + } + else + /* ajout avant */ + { + new_lstGdb->NEXT = pCur; + if (pt == pCur) /* ajout devant la liste */ + return (new_lstGdb); + pCurSup->NEXT = new_lstGdb; + } + return (pt); +} +/*---------------------------------------------------------------------------- +oneBdd :tautologie +------------------------------------------------------------------------------ +renvoie 1 si le graphe est une tautologie +----------------------------------------------------------------------- +parametres :un pointeur de Bdd. +----------------------------------------------------------------------- +return :un int. +------------------------------------------------------------------------------*/ + +int +oneBdd (pBdd) + pNode pBdd; +{ + if (pBdd == one) + return (1); + else + return (0); +} +/*---------------------------------------------------------------------------- +zeroBdd :antilogie +------------------------------------------------------------------------------ +renvoie 1 si le graphe est une antilogie +----------------------------------------------------------------------- +parametres :un pointeur de Bdd. +----------------------------------------------------------------------- +return :un int. +------------------------------------------------------------------------------*/ + +int +zeroBdd (pBdd) + pNode pBdd; +{ + if (pBdd == zero) + return (1); + else + return (0); +} +/*---------------------------------------------------------------------------- +equalBdd :egalite de Bdd +------------------------------------------------------------------------------ +renvoie 1 si Bdd1 = Bdd2 +----------------------------------------------------------------------- +parametres :deux pointeurs de Bdd. +----------------------------------------------------------------------- +return :un short. +------------------------------------------------------------------------------*/ + +int +equalBdd (pBdd1, pBdd2) + pNode pBdd1, pBdd2; +{ + if (pBdd1 == pBdd2) + return (1); + else + return (0); +} + +/*------------------------------------------------------------------------------ +markBdd :met a jour les marques d'un BDD. +------------------------------------------------------- +parametres :un pointeur de Bdd,la valeur du marquage. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +markBdd (pBdd, value) + pNode pBdd; + short value; +{ + if (pBdd->index > 1) + { + if (pBdd->mark != value) /* noeud non encore marque */ + { + pBdd->mark = value; + markBdd (pBdd->high, value); + markBdd (pBdd->low, value); + } + } +} + +/*------------------------------------------------------------------------- +upVarBdd : remonte une variable dans un BDD a l'index i. +--------------------------------------------------------------------------- +retour : un pNode. +---------------------------------------------------------------------------*/ +pNode +upVarBdd (pF, pFoldIndex, newIndex) + pNode pF, pFoldIndex; + short newIndex; +{ + pNode pBddLoc; + + pBddLoc = searchTabLoc (sysBdd.pMC, pF, pFoldIndex, newIndex + 10); + if (pBddLoc != NULL) + return (pBddLoc); + + if (pF->index < pFoldIndex->index) + return (pF); + if (pF->index > newIndex) + pBddLoc = initVertexBdd (pF->index, upVarBdd (pF->high, pFoldIndex, newIndex), + upVarBdd (pF->low, pFoldIndex, newIndex)); + else + /* pF->index < newIndex */ + + pBddLoc = initVertexBdd (newIndex, + constraintBdd (pF, pFoldIndex), + constraintBdd (pF, notBdd (pFoldIndex))); + addTabLoc (sysBdd.pMC, pF, pFoldIndex, pBddLoc, newIndex + 10); + return (pBddLoc); +} +/*------------------------------------------------------------------------- +markAllBdd : marque tous les noeuds BDDs dans la table de reduction . +--------------------------------------------------------------------------- +retour : void. +---------------------------------------------------------------------------*/ +void +markAllBdd (value) + short value; +{ + pNode pBdd, *ppBdd; + int i; + + ppBdd = (sysBdd.pRT)->pBdd; + + for (i = 0; i < sysBdd.pRT->lenTableBdd; i++) + { + pBdd = *ppBdd; + if (pBdd != NULL) + pBdd->mark = value; + ppBdd++; + } +} + +/*------------------------------------------------------------------------- +supportChain_listBdd : calcule le support en noeud d'un graphe. +--------------------------------------------------------------------------- +retour : une liste chainee +---------------------------------------------------------------------------*/ +void +supportBddInt (pt, ppCL) + pNode pt; + chain_list **ppCL; +{ + if (pt->index > 1) + if (pt->mark == 0) + { + *ppCL = addchain (*ppCL, (void *) pt); + supportBddInt (pt->low, ppCL); + supportBddInt (pt->high, ppCL); + pt->mark = 1; + } +} + +chain_list * +supportChain_listBdd (pBdd) + pNode pBdd; +{ + chain_list *res; + + res = NULL; + markBdd (pBdd, 0); + supportBddInt (pBdd, &res); + markBdd (pBdd, 0); + return (res); +} + +/*------------------------------------------------------------------------------ +initVertexBddAux : creation d'un noeud dans la structure sysCible. +------------------------------------------------------- +parametres : index,high,low et system cible. +------------------------------------------------------- +return : le noeud cree. +------------------------------------------------------------------------------*/ +pNode +initVertexBddAux (index, high, low, sysCible) + short index; + pNode high; + pNode low; + struct systemBdd *sysCible; +{ + pNode pt; + + + if ((pt = searchTableBdd (sysCible->pRT, index, high, low)) != NULL) + if (pt != BDDTABLE_PLEINE) + return (pt); + else + { + sysCible->pRT = reAllocTableBdd (sysCible->pRT); + return (initVertexBddAux (index, high, low, sysCible)); + } + + if (high == low) + { + printf ("gcNode : error - there's a node that isn't reduced\n"); + exit (-1); + } + + if (sysCible->indiceAT == MAX_PACK) + { + sysCible->pAT = (pNode) mbkalloc (MAX_PACK * sizeof (struct node)); + sysCible->indiceAT = 1; + sysCible->lpAT = addchain (sysCible->lpAT, (void *) sysCible->pAT); + } + else + { + sysCible->pAT++; + sysCible->indiceAT++; + } + + pt = sysCible->pAT; + pt->index = index; + pt->high = high; + pt->low = low; + pt->mark = 0; + if (index > 1) + if (addTableBdd (sysCible->pRT, pt) == TABLE_PLEINE) /* table pleine */ + { + sysCible->pRT = reAllocTableBdd (sysCible->pRT); + return (initVertexBddAux (index, high, low, sysCible)); + } + return (pt); +} + +/*------------------------------------------------------------------------------ +regenereBdd : regnere un Bdd dans une structure systeme cible. +------------------------------------------------------- +parametres : pointeur Bdd et une structure cible. +------------------------------------------------------- +return : le pointeur dans la structure system cible. +------------------------------------------------------------------------------*/ +pNode +regenereBdd (pBdd, sysCible, pTHNode) + pNode pBdd; + struct systemBdd *sysCible; + pTH pTHNode; +{ + int resul; + + if ((resul = searchTH (pTHNode, (char *)pBdd)) != EMPTYTH) + return ((pNode) resul); + else + { + if (pBdd->index < 2) + { + printf ("gcNode : error - bad index %d\n", pBdd->index); + exit (-1); + } + resul = (int) initVertexBddAux (pBdd->index, + regenereBdd (pBdd->high, sysCible, pTHNode), + regenereBdd (pBdd->low, sysCible, pTHNode), + sysCible); + addTH (pTHNode, (char *)pBdd, resul); + return ((pNode) resul); + } +} +/*------------------------------------------------------------------------------ +gcNodeBdd :effectue un garbage collecteur sur tous les noeuds de systeme + en sauvegardant les noeuds pointes par les pNode de la liste + chainee pChain. +------------------------------------------------------- +parametres : pointeur de chain_list. +------------------------------------------------------- +return : 1 si ok ; + 0 si erreur . +------------------------------------------------------------------------------*/ +void +gcNodeBdd (pt) + chain_list *pt; +{ + struct systemBdd sysBddAux; + pNode zeroAux, oneAux; + pTH pTHNode; + + pTHNode = createTH (MEDIUM); + sysBddAux.pRT = createTableBdd (MEDIUM); + sysBddAux.pMC = createTabLoc (MEDIUM); + sysBddAux.indiceAT = MAX_PACK; + sysBddAux.lpAT = NULL; + zeroAux = initVertexBddAux (0, (pNode) 0, (pNode) 1, &sysBddAux); + oneAux = initVertexBddAux (1, (pNode) 0, (pNode) 1, &sysBddAux); + addTH (pTHNode, (char *)zero, (int) zeroAux); + addTH (pTHNode, (char *)one, (int) oneAux); + + while (pt) + { + pNode ptNode; + ptNode = regenereBdd ((pNode) pt->DATA, &sysBddAux, pTHNode); + pt->DATA = ((void *) ptNode); + pt = pt->NEXT; + } + + destroyBdd (1); + destroyTH (pTHNode); + sysBdd.pRT = sysBddAux.pRT; + sysBdd.pMC = sysBddAux.pMC; + sysBdd.indiceAT = sysBddAux.indiceAT; + sysBdd.lpAT = sysBddAux.lpAT; + sysBdd.pAT = sysBddAux.pAT; + zero = zeroAux; + one = oneAux; +} +/*------------------------------------------------------------------------------ +supportIndexBdd : calcule le support d'un BDD + index decroissant : sens = 1 + index croissant : sens = 0 +------------------------------------------------------- +parametres : pNode +------------------------------------------------------- +return : une liste chainee d'index +------------------------------------------------------------------------------*/ + + /* fonction interne */ + +void +rempTabIndex (pt, tabIndex) + pNode pt; + char *tabIndex; +{ + if (pt->index > 1 && pt->mark == 0) + { + tabIndex[pt->index - 2] = 'O'; + pt->mark = 1; + rempTabIndex (pt->high, tabIndex); + rempTabIndex (pt->low, tabIndex); + } +} + + +chain_list * +supportIndexBdd (pt, sens) + pNode pt; + int sens; +{ + char *tabIndex; + int i; + chain_list *ret; + + /* initialisation du tableau d'index utilises */ + + tabIndex = (char *) mbkalloc (pt->index - 1); + for (i = 0; i <= pt->index - 2; i++) + tabIndex[i] = 'N'; + + rempTabIndex (pt, tabIndex); + markBdd (pt, 0); + + ret = NULL; + + if (sens == 1) /* index decroissant */ + { + for (i = 0; i <= pt->index - 2; i++) + if (tabIndex[i] == 'O') + ret = addchain (ret, i + 2); + } + else + { + for (i = pt->index - 2; i >= 0; i--) + if (tabIndex[i] == 'O') + ret = addchain (ret, i + 2); + } + mbkfree (tabIndex); + return ret; +} diff --git a/alliance/src/log/src/log_bdd1.c b/alliance/src/log/src/log_bdd1.c new file mode 100644 index 00000000..2e40212f --- /dev/null +++ b/alliance/src/log/src/log_bdd1.c @@ -0,0 +1,739 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + + +#ident "$Id: log_bdd1.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + + +/****************************************************************************/ +/* Produit : librairie BDD - Gestion de BDD */ +/****************************************************************************/ + +#include +#include "mut.h" +#include "log.h" + +/*------------------------------------------------------------------------------ +initializeCct :cree un circuit . +------------------------------------------------------- +parametres :nom du circuit, nombre d'entrees et nombre de sorties . +------------------------------------------------------- +return :pointeur de circuit. +------------------------------------------------------------------------------*/ +pCircuit +initializeCct (name, nbI, nbO) + char *name; + int nbI, nbO; +{ + pCircuit pC; + char **pt; + int i; + /* on assure ... */ + nbI++; + nbO++; + + pC = (pCircuit) mbkalloc (sizeof (struct circuit)); + pC->countI = 2; + pC->pTI = createTH (2 * nbI); + pC->pTO = createTH (2 * nbO); + pC->pNameI = (char **) mbkalloc (sizeof (char *) * 2 * nbI); + pt = pC->pNameI; + for (i = 0; i < 2 * nbI; i++) + { + *pt = NULL; + pt++; + } + pC->name = name; + return (pC); +} +/*------------------------------------------------------------------------------ +resetCct :vide un circuit . +------------------------------------------------------- +parametres :pointeur de circuit. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +resetCct (pC) + pCircuit pC; +{ + pElemTH pEl; + short i; + char **pt; + + pEl = (pC->pTI)->pElem; + for (i = 0; i < (pC->pTI)->length; i++) + { + pEl->value = EMPTYTH; + pEl++; + } + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + pEl->value = EMPTYTH; + pEl++; + } + pt = pC->pNameI; + for (i = 0; i < (pC->pTI)->length; i++) + { + *pt = NULL; + pt++; + } + pC->countI = 2; +} + +/*------------------------------------------------------------------------------ +destroyCct :desalloue un circuit . +------------------------------------------------------- +parametres :pointeur de circuit. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +destroyCct (pC) + pCircuit pC; +{ + destroyTH (pC->pTI); + destroyTH (pC->pTO); + mbkfree (pC->pNameI); + mbkfree (pC); +} +/*------------------------------------------------------------------------------ +searchOutputCct :recherche le GDB associe a une sortie . +------------------------------------------------------- +parametres :un pointeur sur le circuit, et le nom de la sortie. +------------------------------------------------------- +return :pointeur de GDB ou null. +------------------------------------------------------------------------------*/ +pNode +searchOutputCct (pC, name) + pCircuit pC; + char *name; +{ + int res; + + if ((res = searchTH (pC->pTO, namealloc (name))) != EMPTYTH) + return ((pNode) res); + else + return (NULL); +} +/*------------------------------------------------------------------------------ +addOutputCct :ajoute un GDB associe a une sortie . +------------------------------------------------------- +parametres :un pointeur sur le GDB,un pointeur de circuit, et le nom + de la sortie. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +addOutputCct (pC, name, pt) + pCircuit pC; + char *name; + pNode pt; +{ + name = namealloc (name); + addTH (pC->pTO, name, (int)pt); +} +/*------------------------------------------------------------------------------ +searchIndexCct :recherche entree associe a un index . +------------------------------------------------------- +parametres :un pointeur sur le circuit, et l'index +------------------------------------------------------- +return : NULL ou le pointeur namealloc +------------------------------------------------------------------------------*/ +char * +searchIndexCct (pC, index) + pCircuit pC; + short index; +{ + if (index <= pC->countI) + return (*(pC->pNameI + index - 2)); + else + return (NULL); +} +/*------------------------------------------------------------------------------ +searchInputCct :recherche index associe a une entree . +------------------------------------------------------- +parametres :un pointeur sur le circuit, et le nom de l' entree. +------------------------------------------------------- +return :index ou EMPTYTH. +------------------------------------------------------------------------------*/ +short +searchInputCct (pC, name) + pCircuit pC; + char *name; +{ + int reallocTH; + int resul; + + reallocTH = (pC->pTI)->length; + resul = searchTH (pC->pTI, namealloc (name)); + + /* on doit reallouer pNameI */ + + if (reallocTH != (pC->pTI)->length) + { + int i, j; + char **pOldName = pC->pNameI; + char **pOldSave = pC->pNameI; + char **pt; + + pC->pNameI = (char **) mbkalloc (sizeof (char *) * (pC->pTI)->length); + pt = pC->pNameI; + for (i = 0; i < (pC->pTI)->length && *pOldName != NULL; i++) + { + *pt = *pOldName; + pt++; + pOldName++; + } + + /* mise a null du reste de la table */ + + for (j = i; j < (pC->pTI)->length; j++) + { + *pt = NULL; + pt++; + } + mbkfree (pOldSave); + } + return (resul); +} +/*------------------------------------------------------------------------------ +addInputCct :ajoute une entree dans la table des var_index. +------------------------------------------------------- +parametres :un pointeur de circuit, et le nom de la variable +------------------------------------------------------- +return :index. +------------------------------------------------------------------------------*/ +short +addInputCct (pC, name) + pCircuit pC; + char *name; +{ + short index; + char **ptName; + + name = namealloc (name); + if ((index = searchInputCct (pC, name)) != EMPTYTH) + { + createNodeTermBdd (index); + return (index); + } + else + { + int reallocTH; + + index = pC->countI; + reallocTH = (pC->pTI)->length; + addTH (pC->pTI, name, index); + + /* on doit reallouer pNameI */ + + if (reallocTH != (pC->pTI)->length) + { + int i, j; + char **pOldName = pC->pNameI; + char **pOldSave = pC->pNameI; + char **pt; + + pC->pNameI = (char **) mbkalloc (sizeof (char *) * (pC->pTI)->length); + pt = pC->pNameI; + for (i = 0; i < (pC->pTI)->length && *pOldName != NULL; i++) + { + *pt = *pOldName; + pt++; + pOldName++; + } + + /* mise a null du reste de la table */ + + for (j = i; j < (pC->pTI)->length; j++) + { + *pt = NULL; + pt++; + } + mbkfree (pOldSave); + } + ptName = pC->pNameI + pC->countI - 2; /* ajout du nom d'INPUT */ + *ptName = name; + pC->countI++; + createNodeTermBdd (index); + return (index); + } +} +/*------------------------------------------------------------------------------ +delInputCct :detruit une entree dans la table des var_index. +------------------------------------------------------- +parametres :un pointeur de circuit, et le nom de la variable +------------------------------------------------------- +return : void. +------------------------------------------------------------------------------*/ +void +delInputCct (pC, name) + pCircuit pC; + char *name; +{ + deleteTH (pC->pTI, name); +} + +/*------------------------------------------------------------------------------ +displayCct :visualise le circuit . +------------------------------------------------------- +parametres :un pointeur de circuit. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +displayCct (pC, mode) + pCircuit pC; + int mode; +{ + pElemTH pEl; + short i, cpt = 0; + + pEl = (pC->pTI)->pElem; + printf ("\n******* DISPLAY %s *******\n", pC->name); + for (i = 0; i < (pC->pTI)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + printf ("INPUT = %s INDEX = %d\n", pEl->key, pEl->value); + pEl++; + } + printf ("\n------------- NUMBER OF INPUTS : %d\n\n", (pC->countI) - 2); + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + markBdd ((pNode)pEl->value, 0); + pEl++; + } + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + cpt++; + printf ("OUTPUT = %s", pEl->key); + if (mode == 0) + { + printf (" BDD = %d\n", pEl->value); + displayBddName (TRUE, (pNode)pEl->value, pC->pNameI); + } + else + { + printf ("\n%s = ", pEl->key); + displayExpr (bddToAbl ((pNode)pEl->value, pC->pNameI)); + } + printf ("\n"); + } + pEl++; + } + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + markBdd ((pNode)pEl->value, 0); + pEl++; + } + printf ("------------- NUMBER OF OUTPUTS : %d\n", cpt); + printf ("**************************************\n\n"); +} +/*------------------------------------------------------------------------------ +composeCct :compose tous les GDB de pC en expansant l'entree name . +------------------------------------------------------- +parametres :un pointeur de circuit,nom d'entree,le GDB associe. +------------------------------------------------------- +return :rien . +------------------------------------------------------------------------------*/ +void +composeCct (pC, name, pt) + pCircuit pC; + char *name; + pNode pt; +{ + int i; + short index; + pElemTH pEl; + + pEl = (pC->pTO)->pElem; /* pointeur courant de la table pTI */ + index = searchInputCct (pC, name); + if (index == EMPTYTH) + { + printf ("bdd1-composeCct : la variable a expanser n'est pas une entree\n"); + exit (-1); + } + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + pEl->value = (int) composeBdd ((pNode)pEl->value, pt, index); + pEl++; + } + deleteTH (pC->pTI, name); /* on elimine name des INPUT */ +} + +/*------------------------------------------------------------------------------ +constraintCct :contraint tous les GDB de pC avec le GDB pointe par pt . +------------------------------------------------------- +parametres :un pointeur de circuit,le GDB . +------------------------------------------------------- +return :rien . +------------------------------------------------------------------------------*/ +void +constraintCct (pC, pt) + pCircuit pC; + pNode pt; +{ + int i; + pElemTH pEl; + + pEl = (pC->pTO)->pElem; /* pointeur courant de la table pTO */ + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + pEl->value = (int) constraintBdd ((pNode)pEl->value, pt); + pEl++; + } +} +/*------------------------------------------------------------------------------ +proofCct :preuve formelle de circuits . +------------------------------------------------------- +parametres :deux pointeurs de circuits . +------------------------------------------------------- +return :rien . +------------------------------------------------------------------------------*/ +void +proofCct (pC1, pC2) + pCircuit pC1, pC2; +{ + pElemTH pEl; + pNode noeudCC2; + int i; + short indexCC2; + chain_list *expr; + + printf ("\n\n******* PROOF between %s & %s *******\n", pC1->name, pC2->name); + pEl = (pC1->pTI)->pElem; /* pointeur courant de la table pTI */ + for (i = 0; i < (pC1->pTI)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + /* recherche dans CC2 */ + + indexCC2 = searchTH (pC2->pTI, pEl->key); + + + if (pEl->value != indexCC2) + { + printf ("INDEX (%s) differents pour les deux circuits\n", pEl->key); + printf ("********** END OF PROOF **********\n\n"); + break; + } + } + } + + pEl = (pC1->pTO)->pElem; /* pointeur courant de la table CC1 */ + + for (i = 0; i < (pC1->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + /* recherche dans CC2 */ + + noeudCC2 = (pNode) searchTH (pC2->pTO, pEl->key); + + + if (noeudCC2 != (pNode) EMPTYTH) + { + printf ("OUTPUT %s ", pEl->key); + if (noeudCC2 == (pNode) pEl->value) + printf ("is equal\n"); + else + { + printf ("is different\n"); + printf ("%s = ", pEl->key); + expr = bddToAbl ((pNode) pEl->value, pC1->pNameI); + if (numberAtomExpr (expr) < 50) + displayExpr (expr); + else + printf ("too small..."); + printf ("\n"); + printf ("%s = ", pEl->key); + expr = bddToAbl (noeudCC2, pC2->pNameI); + if (numberAtomExpr (expr) < 50) + displayExpr (expr); + else + printf ("too small..."); + printf ("\n"); + } + } + } + pEl++; + } + printf ("********** END OF PROOF **********\n\n"); +} + +/*------------------------------------------------------------------------------ +ablToBddCct :traduit la forme prefixee ABL en un GDB . +------------------------------------------------------- +parametres : un circuit et un pointeur d'ABL . +------------------------------------------------------- +return :GDB . +------------------------------------------------------------------------------*/ +pNode +ablToBddCct (pC, expr) + pCircuit pC; + chain_list *expr; +{ + short oper; + pNode pt; + chain_list *lstGdb; + + if (ATOM (expr)) + { + if ((pt = searchOutputCct (pC, VALUE_ATOM (expr))) != NULL) + return (pt); + else + { + if (!strcmp (VALUE_ATOM (expr), "'0'")) + return (zero); + if (!strcmp (VALUE_ATOM (expr), "'d'")) + return (zero); + if (!strcmp (VALUE_ATOM (expr), "'1'")) + return (one); + pt = createNodeTermBdd (addInputCct (pC, VALUE_ATOM (expr))); + return (pt); + } + } + else + { + oper = OPER (expr); + lstGdb = NULL; + while ((expr = CDR (expr))) + lstGdb = addListBdd (lstGdb, ablToBddCct (pC, CAR (expr))); + pt = applyBdd (oper, lstGdb); + freechain (lstGdb); + return (pt); + } +} +/*------------------------------------------------------------------------------ +cpOrderCct :copie la table des index de CC1 dans CC2 . +------------------------------------------------------- +parametres :deux pointeurs de circuits. + de la sortie. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +void +cpOrderCct (CC1, CC2) + pCircuit CC1, CC2; +{ + int i; + pElemTH pEl1; + pElemTH pEl2; + char **pt1, **pt2; + pTH tab; + + if (CC2->pTI->length != CC1->pTI->length) + { + tab = createTH ((CC1->pTI->length)); + destroyTH (CC2->pTI); + CC2->pTI = tab; + } + pEl1 = (CC1->pTI)->pElem; + pEl2 = (CC2->pTI)->pElem; + for (i = 0; i < (CC1->pTI)->length; i++) + { + pEl2->value = pEl1->value; + pEl2->key = pEl1->key; + pEl1++; + pEl2++; + } + CC2->pTI->count = CC1->pTI->count; + CC2->countI = CC1->countI; + pt1 = CC1->pNameI; + pt2 = CC2->pNameI; + for (i = 0; i < CC1->countI; i++) + { + *pt2 = *pt1; + pt1++; + pt2++; + } +} + +/*------------------------------------------------------------------------- +upVarCct : remontee d'une variable dans un circuit +--------------------------------------------------------------------------- +retour : un void. +---------------------------------------------------------------------------*/ + +void +upVarCct (pC, ptOldIndex, newIndex) + pCircuit pC; + pNode ptOldIndex; + short newIndex; +{ + int i; + pElemTH pEl; + + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + pEl->value = (int) upVarBdd ((pNode)pEl->value, ptOldIndex, newIndex); + pEl++; + } + deleteTH (pC->pTI, *(pC->pNameI + newIndex - 2)); + *(pC->pNameI + newIndex - 2) = *(pC->pNameI + ptOldIndex->index - 2); + addTH (pC->pTI, *(pC->pNameI + ptOldIndex->index - 2), newIndex); +} + +/*------------------------------------------------------------------------- +numberNodeCct : calcule le nombre de noeud d'un circuit +--------------------------------------------------------------------------- +retour : un entier. +---------------------------------------------------------------------------*/ + +int +numberNodeCct (pC) + pCircuit pC; +{ + pElemTH pEl; + int i, number_node; + + number_node = 0; + markAllBdd (0); + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + number_node = number_node + countNode ((pNode) pEl->value); + } + pEl++; + } + markAllBdd (0); + return (number_node); +} + +/*------------------------------------------------------------------------- +numberNodeTdgCct : calcule le nombre de noeud equivalent TDG d'un circuit +--------------------------------------------------------------------------- +retour : un entier. +---------------------------------------------------------------------------*/ + +int +numberNodeTdgCct (pC) + pCircuit pC; +{ + pElemTH pEl; + int i, number_node; + + number_node = 0; + markAllBdd (0); + pEl = (pC->pTO)->pElem; + for (i = 0; i < (pC->pTO)->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + number_node = number_node + countNodeTdg ((pNode) pEl->value); + } + pEl++; + } + markAllBdd (0); + return (number_node); +} + +/*------------------------------------------------------------------------------ +bddToAblCct :traduit un BDD en ABL d'une maniere simplifie. +------------------------------------------------------- +parametres :un pointeur de NODE. +------------------------------------------------------- +return :une pointeur de CHAIN_LIST. +------------------------------------------------------------------------------*/ +chain_list * +bddToAblCct (pC, pBdd) + pCircuit pC; + pNode pBdd; +{ + return (bddToAbl (pBdd, pC->pNameI)); +} + +/*------------------------------------------------------------------------------ +gcNodeCct :effectue un garbage collecteur sur tous les noeuds de systeme + en sauvegardant les noeuds pointes par les pNode(s) du circuit. +------------------------------------------------------- +parametres : pointeur de chain_list. +------------------------------------------------------- +return : 1 si ok ; + 0 si erreur . +------------------------------------------------------------------------------*/ +void +gcNodeCct (pC) + pCircuit pC; +{ + struct systemBdd sysBddAux; + pNode zeroAux, oneAux; + pTH pTHNode; + pElemTH pEl; + int j; + + pTHNode = createTH (MEDIUM); + sysBddAux.pRT = createTableBdd (MEDIUM); + sysBddAux.pMC = createTabLoc (MEDIUM); + sysBddAux.indiceAT = MAX_PACK; + sysBddAux.lpAT = NULL; + zeroAux = initVertexBddAux (0, (pNode) 0, (pNode) 1, &sysBddAux); + oneAux = initVertexBddAux (1, (pNode) 0, (pNode) 1, &sysBddAux); + addTH (pTHNode, (char *)zero, (int) zeroAux); + addTH (pTHNode, (char *)one, (int) oneAux); + + + /* on regenere les graphes */ + + pEl = (pC->pTO)->pElem; + for (j = 0; j < (pC->pTO)->length; j++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + pEl->value = (int) regenereBdd ((pNode) pEl->value, &sysBddAux, pTHNode); + pEl++; + } + + destroyBdd (1); + destroyTH (pTHNode); + sysBdd.pRT = sysBddAux.pRT; + sysBdd.pMC = sysBddAux.pMC; + sysBdd.indiceAT = sysBddAux.indiceAT; + sysBdd.lpAT = sysBddAux.lpAT; + sysBdd.pAT = sysBddAux.pAT; + zero = zeroAux; + one = oneAux; +} diff --git a/alliance/src/log/src/log_prefbib.c b/alliance/src/log/src/log_prefbib.c new file mode 100644 index 00000000..8ec31cd0 --- /dev/null +++ b/alliance/src/log/src/log_prefbib.c @@ -0,0 +1,2138 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + + +#ident "$Id: log_prefbib.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + +/****************************************************************************/ +/* Produit : librairie ABL - Gestion de representations prefixees */ +/****************************************************************************/ + +#include +#include +#include +#include + +#include "mut.h" +#include "log.h" + +#undef MIN_OPER +#undef MAX_OPER +#define MIN_OPER 0 +#define MAX_OPER 1000 + +/*------------------------------------------------------------------------- +gensym_abl : calcule un identificateur avec concatenation d'un numero. +--------------------------------------------------------------------------- +retour : un pointeur de chaine de caracteres. +---------------------------------------------------------------------------*/ +char * +gensym_abl (name, num) + char *name; + int num; +{ + char *name1; + char number[3]; + char *ret; + + name1 = (char *) mbkalloc (strlen (name) + 5); + (void *) strcpy (name1, name); + sprintf (number, "%d", num); + strcat (name1, number); + ret = namealloc (name1); + mbkfree (name1); + + return ret; +} + +/*================ Gestion des erreurs ====================*/ + +/*------------------------------------------------------------------ + IDENT : ablError + ------------------------------------------------------------------ + FUNCTION : verifie que expr est bien une expression. func est le nom + la fonction appelante. + ------------------------------------------------------------------ */ +void +ablError (expr, func) + chain_list *expr; + char *func; +{ + int oper = OPER (expr); + + if (oper < MIN_OPER || oper > MAX_OPER) + { + printf ("\nablError :\n%s: error - bad operator\n", func); + exit (-1); + } +} + +/*================ Creation et destruction d'ABL ====================*/ + +/*------------------------------------------------------------------ + IDENT : createAtom + ------------------------------------------------------------------ + FUNCTION : cree un atome (un doublet) avec son CAR qui pointe sur + name et son CDR egal a NULL. + ------------------------------------------------------------------ */ +chain_list * +createAtom (name) + char *name; +{ + return addchain (NULL, (void *) namealloc (name)); +} + +/*------------------------------------------------------------------ + IDENT : createExpr + ------------------------------------------------------------------ + FUNCTION : cree une tete d'expression ayant oper comme operateur. + ------------------------------------------------------------------ */ +chain_list * +createExpr (oper) + short oper; +{ + /* POUR GNU : le cast (void *)oper a ete enleve' */ + if (oper >= MIN_OPER && oper <= MAX_OPER) + return addchain (NULL, (void *) addchain (NULL, oper)); + else + { + printf ("\ncreateExpr: error - unknown operator %d\n", oper); + exit (-1); + } +} + +/*------------------------------------------------------------------ + IDENT : notExpr + ------------------------------------------------------------------ + FUNCTION : ajoute un NOT sur une expression. + ------------------------------------------------------------------ */ +chain_list * +notExpr (expr) + chain_list *expr; +{ + chain_list *expr1; + + if (!ATOM (expr) && OPER (expr) == NOT) /* simplification */ + { + expr1 = CAR (CDR (expr)); + delchain (CAR (expr), CAR (expr)); /* desalloue l'operateur */ + freechain (expr); + return expr1; + } + expr1 = createExpr (NOT); + addHExpr (expr1, expr); + return expr1; +} + +/*------------------------------------------------------------------ + IDENT : createBinExpr + ------------------------------------------------------------------ + FUNCTION : creer une expression a partir de deux expressions + avec fusion possible des operateurs. + ------------------------------------------------------------------ */ +chain_list * +createBinExpr (oper, expr1, expr2) + short oper; + chain_list *expr1, *expr2; +{ + chain_list *expr, *exprp; + + if (oper < MIN_OPER || oper > MAX_OPER || oper == NOT) + { + printf ("\ncreateBinExpr: error - bad operator %d\n", oper); + exit (-1); + } + + if (ATOM (expr1) || (OPER (expr1) != oper) || + ((oper == NOR) || (oper == NAND) || (oper == NXOR))) + { + /* non-compactage sur l'operateur */ + expr = createExpr (oper); + addHExpr (expr, expr1); + } + else + { + expr = expr1; + } + + if (ATOM (expr2) || (OPER (expr2) != oper) || + ((oper == NOR) || (oper == NAND) || (oper == NXOR))) + { + /* non-compactage sur l'operateur */ + addHExpr (expr, expr2); + } + else + { + /* Fusion de expr2 dans expr */ + exprp = expr2; + while (CDR (exprp) != NULL) + { + exprp = CDR (exprp); + } + exprp->NEXT = expr->NEXT; + expr->NEXT = expr2->NEXT; + expr2->NEXT = NULL; /* desa. de la tete de expr2 */ + freeExpr (expr2); + } + return (expr); +} + +/*------------------------------------------------------------------ + IDENT : addQExpr + ------------------------------------------------------------------ + FUNCTION : ajoute a la fin d'une expression un nouvel argument. + ------------------------------------------------------------------ */ +void +addQExpr (expr1, expr2) + chain_list *expr1, *expr2; +{ + ablError (expr1, "addQExpr"); + + while (CDR (expr1)) + expr1 = CDR (expr1); + expr1->NEXT = addchain (NULL, (void *) expr2); +} + +/*------------------------------------------------------------------ + IDENT : addHExpr + ------------------------------------------------------------------ + FUNCTION : ajoute au debut d'une expression un nouvel argument. + ------------------------------------------------------------------ */ +void +addHExpr (expr1, expr2) + chain_list *expr1, *expr2; +{ + ablError (expr1, "addHExpr"); + + expr1->NEXT = addchain (expr1->NEXT, (void *) expr2); +} + +/*------------------------------------------------------------------ + IDENT : freeExpr + ------------------------------------------------------------------ + FUNCTION : Desalloue l'expression jusqu'aux atomes. + ------------------------------------------------------------------ */ +void +freeExpr (expr) + chain_list *expr; +{ + chain_list *pt; + + if (expr) + { + if (ATOM (expr)) + freechain (expr); + else + { + pt = expr; + delchain (CAR (expr), CAR (expr)); /* desalloue l'operateur */ + while ((expr = CDR (expr))) /* puis les ss-expr... */ + freeExpr (CAR (expr)); + freechain (pt); + } + } +} + +/*============================ Affichage ============================*/ + +/*------------------------------------------------------------------ + IDENT : operToChar + ------------------------------------------------------------------ + FUNCTION : renvoie la chaine de car. correspondant a l'operateur + oper. + ------------------------------------------------------------------ */ +char * +operToChar (oper) + short oper; +{ + if (oper >= MIN_OPER && oper <= MAX_OPER) + { + switch (oper) + { + case NOT: + return (namealloc ("not")); + case AND: + return (namealloc ("and")); + case OR: + return (namealloc ("or")); + case NAND: + return (namealloc ("nand")); + case NOR: + return (namealloc ("nor")); + case XOR: + return (namealloc ("xor")); + case NXOR: + return (namealloc ("nxor")); + case STABLE: + return (namealloc ("stable")); + default: + return (namealloc ("???")); + } + } + else + { + printf ("\nablError - operToChar: unknown operator %d\n", oper); + exit (-1); + } +} + +/*------------------------------------------------------------------ + IDENT : charToOper + ------------------------------------------------------------------ + FUNCTION : renvoie le numero d'oper. correspondant a l'ident name. + ------------------------------------------------------------------ */ +short +charToOper (name) + char *name; +{ + if (name == namealloc ("not")) + return (NOT); + if (name == namealloc ("and")) + return (AND); + if (name == namealloc ("or")) + return (OR); + if (name == namealloc ("xor")) + return (XOR); + if (name == namealloc ("nand")) + return (NAND); + if (name == namealloc ("nor")) + return (NOR); + if (name == namealloc ("nxor")) + return (NXOR); + if (name == namealloc ("stable")) + return (STABLE); + return (-1); +} + +/*------------------------------------------------------------------ + IDENT : displayExprInt + ------------------------------------------------------------------ + FUNCTION : affiche l'expression a la sauce LISP --> (oper list_arg) + ------------------------------------------------------------------ */ +void +displayExprInt (expr) + chain_list *expr; +{ + int oper; + + if (ATOM (expr)) + printf (" %s", VALUE_ATOM (expr)); + else + { + oper = OPER (expr); + if (oper >= MIN_OPER && oper <= MAX_OPER) + { + printf (" (%s", operToChar (OPER (expr))); + mapExpr (displayExprInt, expr); + printf (")"); + } + else + { + printf ("\ndisplayExpr : error - unknown operator %d\n", oper); + exit (-1); + } + } +} + +/*------------------------------------------------------------------ + IDENT : displayExpr + ------------------------------------------------------------------ + FUNCTION : affiche l'expression a la sauce LISP --> (oper list_arg) + + saut a la ligne + ------------------------------------------------------------------ */ +void +displayExpr (expr) + chain_list *expr; +{ + displayExprInt (expr); + printf ("\n"); +} + +/*------------------------------------------------------------------ + IDENT : displayInfExpr + ------------------------------------------------------------------ + FUNCTION : affiche l'ABL "expr" en infixe + ------------------------------------------------------------------ */ +void +displayInfExpr (expr) + chain_list *expr; +{ + int oper; + + if (ATOM (expr)) /* Traitement atomique */ + printf ("%s", VALUE_ATOM (expr)); + else + /* Traitement d'expression */ + { + oper = OPER (expr); /* Sauvegarde de l'operateur */ + if (oper == NOT) /* Traitement du NOT */ + { + printf ("not "); + displayInfExpr (CAR (CDR (expr))); + } + else + /* Traitement des autres operateurs */ + { + printf ("("); + while ((expr = CDR (expr))) + { + displayInfExpr (CAR (expr)); + if (CDR (expr)) /* Un operateur en moins que */ + printf (" %s ", operToChar (oper)); /* le nombre d'arguments */ + } + printf (")"); + } + } +} + +/*------------------------------------------------------------------ + IDENT : exprToCharInt + ------------------------------------------------------------------ + FUNCTION : renvoie une chaine de caracteres correspondant a la fonction + en mode infixe (mode = 1) ou en mode prefixe (mode = 0) + ------------------------------------------------------------------ */ +char * +exprToCharInt (expr, mode, chaine, taille) + chain_list *expr; + int mode; + char *chaine; + int *taille; +{ + char *oper; + int lenVA; + + if (ATOM (expr)) + { + if (*taille < strlen (chaine) + 50) /* re-allocation */ + { + *taille = *taille + 100; + chaine = (char *) realloc (chaine, *taille); + } + lenVA = strlen (VALUE_ATOM (expr)); + + strncat (chaine, VALUE_ATOM (expr), lenVA); + return (chaine); + } + else + { + oper = operToChar (OPER (expr)); + + if (mode) +/*---- infixe ----*/ + { + if (OPER (expr) == NOT) + { + strncat (chaine, "not ", 4); + chaine = exprToCharInt (CAR (CDR (expr)), mode, chaine, taille); + return (chaine); + } + else if (OPER (expr) == STABLE) + { + chaine = exprToCharInt (CAR (CDR (expr)), mode, chaine, taille); + strncat (chaine, "'stable ", 8); + return (chaine); + } + else + { + strncat (chaine, "(", 1); + while ((expr = CDR (expr))) + { + chaine = exprToCharInt (CAR (expr), mode, chaine, taille); + if (CDR (expr)) + { + strncat (chaine, " ", 1); + strcat (chaine, oper); + strncat (chaine, " ", 1); + } + } + strncat (chaine, ")", 1); + return (chaine); + } + } + else +/*----- prefixe -----*/ + { + int lenOPER = strlen (oper); + strncat (chaine, "(", 1); + strncat (chaine, oper, lenOPER); + while ((expr = CDR (expr))) + { + strncat (chaine, " ", 1); + chaine = exprToCharInt (CAR (expr), mode, chaine, taille); + } + strncat (chaine, ")", 1); + return (chaine); + } + } +} + +/*------------------------------------------------------------------ + IDENT : exprToChar + ------------------------------------------------------------------ + FUNCTION : renvoie une chaine de caracteres correspondant a la fonction + en mode infixe (mode = 1) ou en mode prefixe (mode = 0) + ------------------------------------------------------------------ */ +char * +exprToChar (expr, mode) + chain_list *expr; + int mode; +{ + char *chaine; + int taille; + + taille = 100; + chaine = (char *) mbkalloc (100); + chaine[0] = '\0'; + + return exprToCharInt (expr, mode, chaine, &taille); +} + +/*------------------------------------------------------------------ + IDENT : identExprInt + ------------------------------------------------------------------ + FUNCTION : renvoie une chaine de caracteres correspondant a un nom + d'expression aux variables pres. + ------------------------------------------------------------------ */ +char * +identExprInt (expr, chaine, taille) + chain_list *expr; + char *chaine; + int *taille; +{ + if (ATOM (expr)) + return chaine; + else + { + chain_list *expr1; + char arite[3]; + int oper = OPER (expr); + + switch (oper) + { + case NOT: + strncat (chaine, "n", 1); + break; + case AND: + strncat (chaine, "a", 1); + break; + case OR: + strncat (chaine, "o", 1); + break; + case NAND: + strncat (chaine, "na", 2); + break; + case NOR: + strncat (chaine, "no", 2); + break; + case XOR: + strncat (chaine, "x", 1); + break; + case NXOR: + strncat (chaine, "nx", 2); + break; + default: + strncat (chaine, "???", 3); + } + expr1 = expr; + while ((expr = CDR (expr))) + { + chaine = identExprInt (CAR (expr), chaine, taille); + } + if (oper != NOT) + { + sprintf (arite, "%d", lengthExpr (expr1)); + strcat (chaine, arite); + } + return (chaine); + } +} + + +/*------------------------------------------------------------------ + IDENT : identExpr + ------------------------------------------------------------------ + FUNCTION : renvoie une chaine de caracteres correspondant a un nom + d'expression aux variables pres. + ------------------------------------------------------------------ */ +char * +identExpr (expr) + chain_list *expr; +{ + char *chaine, *bidon; + int taille, i; + chain_list *expr1; + int flag_alloc = 0; + + taille = 100; + + /* normalisation */ + flatArityExpr (expr); + if (searchOperExpr (expr, NOT)) + { + if (!searchOperExpr (expr, XOR)) + { + flag_alloc = 1; + expr1 = flatPolarityExpr (expr, 1); + if (searchOperExpr (expr1, NOT)) + { + expr = notExpr (flatPolarityExpr (expr1, 0)); + freeExpr (expr1); + } + else + { + expr = expr1; + } + } + } + + if (profExpr (expr) == 1) + { + chaine = gensym_abl (operToChar (OPER (expr)), lengthExpr (expr)); + } + else if (profExpr (expr) == 2 && OPER (expr) == NOT) + { + bidon = (char *) mbkalloc (taille); + bidon[0] = 'n'; + bidon[1] = '\0'; + strcat (bidon, operToChar (OPER (CADR (expr)))); + chaine = gensym_abl (bidon, lengthExpr (CADR (expr))); + mbkfree (bidon); + } + else + { + bidon = (char *) mbkalloc (taille); + bidon[0] = '\0'; + bidon = identExprInt (expr, bidon, &taille); + for (i = strlen (bidon) - 1; bidon[i] == '_'; i--) + bidon[i] = '\0'; + chaine = namealloc (bidon); + mbkfree (bidon); + } + if (flag_alloc) + freeExpr (expr); + + return chaine; +} + +/*------------------------------------------------------------------ + IDENT : profExpr + ------------------------------------------------------------------ + FUNCTION : calcule la profondeur d'une expression. + ------------------------------------------------------------------*/ +int +profExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return 0; + else + { + int max = 0, profCar; + + while ((expr = CDR (expr))) + { + profCar = profExpr (CAR (expr)); + if (profCar > max) + max = profCar; + } + return ++max; + } +} + +/*------------------------------------------------------------------ + IDENT : profAOExpr + ------------------------------------------------------------------ + FUNCTION : calcule la profondeur d'une expression sans tenir compte + des inverseurs. + ------------------------------------------------------------------*/ +int +profAOExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return 0; + else + { + int max = 0, profCar, oper = OPER (expr); + + while ((expr = CDR (expr))) + { + profCar = profAOExpr (CAR (expr)); + if (profCar > max) + max = profCar; + } + if (oper == NOT) + return max; + + return ++max; + } +} + +/*======================= Les fonctionnelles ========================*/ + +/*------------------------------------------------------------------ + IDENT : mapCarExpr + ------------------------------------------------------------------ + FUNCTION : applique la fonction func sur l'expression expr et + renvoie une expression ayant oper comme operateur et + ayant pour ss-expr. le resultat de l'application de + func sur les ss-expr. de expr. + ------------------------------------------------------------------*/ +chain_list * +mapCarExpr (func, oper, expr) + chain_list *(*func) (); + short oper; + chain_list *expr; +{ + chain_list *pt; + + pt = createExpr (oper); + while ((expr = CDR (expr))) + addQExpr (pt, (*func) (CAR (expr))); + return pt; +} + +/*------------------------------------------------------------------ + IDENT : mapExpr + ------------------------------------------------------------------ + FUNCTION : applique la fonction func sur l'expression expr. + func doit renvoye un void et prendre comme argument un + pointeur de chain_list. + ------------------------------------------------------------------*/ +void +mapExpr (func, expr) + void (*func) (); + chain_list *expr; +{ + while ((expr = CDR (expr))) + (*func) (CAR (expr)); +} + +/*------------------------------------------------------------------ + IDENT : anyExpr + ------------------------------------------------------------------ + FUNCTION : applique la fonction func sur l'expression expr. + renvoie 1 s'il y a eu au moins un appel de func qui a + renvoye 1. (OU logique) + ------------------------------------------------------------------*/ +int +anyExpr (func, expr) + int (*func) (); + chain_list *expr; +{ + while ((expr = CDR (expr))) + if ((*func) (CAR (expr))) + return 1; + + return 0; +} + +/*------------------------------------------------------------------ + IDENT : EveryExpr + ------------------------------------------------------------------ + FUNCTION : applique la fonction func sur l'expression expr. + renvoie 1 si tout les appels de func ont renvoye 1. + (ET logique) + ------------------------------------------------------------------*/ +int +everyExpr (func, expr) + int (*func) (); + chain_list *expr; +{ + while ((expr = CDR (expr))) + if (!((*func) (CAR (expr)))) + return 0; + + return 1; +} + +/*====================== Manipulations d'ABL =========================*/ + +/*------------------------------------------------------------------ + IDENT : searchOperExpr + ------------------------------------------------------------------ + FUNCTION : renvoie 1 si oper existe dans expr, 0 sinon. + ------------------------------------------------------------------*/ +int +searchOperExpr (expr, oper) + chain_list *expr; + short oper; +{ + if (ATOM (expr)) + return 0; + else if (OPER (expr) == oper) + return 1; + else + { + while ((expr = CDR (expr))) + if (searchOperExpr (CAR (expr), oper) == 1) + return 1; + return 0; + } +} + +/*------------------------------------------------------------------ + IDENT : searchExprLow + ------------------------------------------------------------------ + FUNCTION : renvoie 1 si name existe dans expr, 0 sinon. + ------------------------------------------------------------------*/ +short +searchExprLow (expr, name) + chain_list *expr; + char *name; +{ + if (ATOM (expr)) + if (name == VALUE_ATOM (expr)) + return 1; + else + return 0; + else + { + while ((expr = CDR (expr))) + if (searchExprLow (CAR (expr), name)) + return 1; + return 0; + } +} + +/*------------------------------------------------------------------ + IDENT : searchExpr + ------------------------------------------------------------------ + FUNCTION : renvoie 1 si namealloc(name) existe dans expr, 0 sinon. + ------------------------------------------------------------------*/ +int +searchExpr (expr, name) + chain_list *expr; + char *name; +{ + + return searchExprLow (expr, namealloc (name)); +} + +/*------------------------------------------------------------------ + IDENT : equalExpr + ------------------------------------------------------------------ + FUNCTION : renvoie 1 si expr1 = expr2, 0 sinon. + ------------------------------------------------------------------*/ +int +equalExpr (expr1, expr2) + chain_list *expr1, *expr2; +{ + if (ATOM (expr1)) + if (ATOM (expr2) && (CAR (expr1) == CAR (expr2))) + return 1; + else + return 0; + if (ATOM (expr2)) + return 0; + else + { + if (OPER (expr1) != OPER (expr2)) /* egalite des operateurs */ + return 0; + expr1 = CDR (expr1); + expr2 = CDR (expr2); + while (expr1 && expr2) + { + if (!(equalExpr (CAR (expr1), CAR (expr2)))) + return 0; + expr1 = CDR (expr1); + expr2 = CDR (expr2); + } + if (expr2 || expr1) + return 0; + else + return 1; + } +} + +/*------------------------------------------------------------------ + IDENT : equalVarExpr + ------------------------------------------------------------------ + FUNCTION : renvoie 1 si expr1 = expr2 aux variables pres, 0 sinon. + ------------------------------------------------------------------*/ +int +equalVarExpr (expr1, expr2) + chain_list *expr1, *expr2; +{ + if (ATOM (expr1)) + { + if (ATOM (expr2)) + return 1; + else + return 0; + } + if (ATOM (expr2)) + return 0; + else + { + if (OPER (expr1) != OPER (expr2)) /* egalite des operateurs */ + return 0; + expr1 = CDR (expr1); + expr2 = CDR (expr2); + while (expr1 && expr2) + { + if (!(equalVarExpr (CAR (expr1), CAR (expr2)))) + return 0; + expr1 = CDR (expr1); + expr2 = CDR (expr2); + } + if (expr2 || expr1) + return 0; + else + return 1; + } +} + +/*------------------------------------------------------------------ + IDENT : lengthExpr + ------------------------------------------------------------------ + FUNCTION : renvoie la taille de l'expression au premier niveau. + (en fait l'arite de l'operateur) + ------------------------------------------------------------------*/ +int +lengthExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return 1; + else + { + int cpt = 0; + + while ((expr = CDR (expr))) + cpt++; + return cpt; + } +} + +/*------------------------------------------------------------------ + IDENT : numberOperBinExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le nombre d'operateurs binaires (equivalent) + d'une expression. + ------------------------------------------------------------------*/ +int +numberOperBinExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return 0; + else + { + int cpt = -1; + + if (OPER (expr) == NOT) + return numberOperBinExpr (CADR (expr)); + + while ((expr = CDR (expr))) + cpt = 1 + cpt + numberOperBinExpr (CAR (expr)); + + return cpt; + } +} + +/*------------------------------------------------------------------ + IDENT : numberAtomExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le nombre d'atomes de l'expression. + ------------------------------------------------------------------*/ +int +numberAtomExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return 1; + else + { + int cpt = 0; + + while ((expr = CDR (expr))) + cpt += numberAtomExpr (CAR (expr)); + + return cpt; + } +} + +/*------------------------------------------------------------------ + IDENT : copyExpr + ------------------------------------------------------------------ + FUNCTION : renvoie une expression qui correspond a une recopie de + expr (avec l'arite). + ------------------------------------------------------------------*/ +chain_list * +copyExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return addchain (NULL, expr->DATA); + else + { + chain_list *auxExpr; + chain_list *oldExpr = expr; + chain_list *expr1; + + auxExpr = createExpr (OPER (expr)); + expr1 = auxExpr; + + while ((expr = CDR (expr))) + { + /* on optimise a fond la recopie de la dorsale */ + expr1->NEXT = addchain (NULL, (void *) copyExpr (CAR (expr))); + expr1 = CDR (expr1); + + /* remplace : addQExpr(auxExpr,copyExpr(CAR(expr))); */ + } + + /* on sauvegarde la poubelle */ + ((chain_list *) auxExpr->DATA)->NEXT = CDR (CAR (oldExpr)); + return (auxExpr); + } +} +/*------------------------------------------------------------------ + IDENT : substPhyExpr + ------------------------------------------------------------------ + FUNCTION : substitue toutes les occurences de "name" dans expr1 par + l'expression expr2. + ------------------------------------------------------------------*/ +void +substPhyExpr (expr1, name, expr2) + chain_list *expr1; + char *name; + chain_list *expr2; +{ + if (!ATOM (expr1)) + { + while ((expr1 = CDR (expr1))) + if (ATOM (CAR (expr1))) + { + if (!strcmp (name, VALUE_ATOM (CAR (expr1)))) + { + freechain (CAR (expr1)); + expr1->DATA = (void *) copyExpr (expr2); + } + } + else + substPhyExpr (CAR (expr1), name, expr2); + } +} + +/*------------------------------------------------------------------ + IDENT : substExpr + ------------------------------------------------------------------ + FUNCTION : renvoie une expression dans laquelle on a substitue + toutes les occurences de "name" par l'expression expr2. + ------------------------------------------------------------------*/ +chain_list * +substExpr (expr1, name, expr2) + chain_list *expr1; + char *name; + chain_list *expr2; +{ + if (ATOM (expr1)) + if (!strcmp (name, VALUE_ATOM (expr1))) + return copyExpr (expr2); + else + return copyExpr (expr1); + else + { + chain_list *res = createExpr (OPER (expr1)); + + while ((expr1 = CDR (expr1))) + addQExpr (res, substExpr (CAR (expr1), name, expr2)); + + return res; + } +} + +/*------------------------------------------------------------------ + IDENT : devXorExpr + ------------------------------------------------------------------ + FUNCTION : developpe recursivement les XOR dans une expression. + a xor b = ((not a) and b) or (a and (not b)) + ------------------------------------------------------------------*/ +chain_list * +devXorExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return copyExpr (expr); + else + { + if (OPER (expr) != XOR) + return mapCarExpr (devXorExpr, OPER (expr), expr); + else if (lengthExpr (expr) == 2) + { + chain_list *dev, *ret; + + dev = devXor2Expr (expr); + ret = devXorExpr (dev); + freeExpr (dev); + return (ret); + } + else + { + /* XOR N>2 */ + chain_list *xor, *dev, *inter; + + xor = createExpr (XOR); + addHExpr (xor, copyExpr (CADR (expr))); + + /* elimination du premier arg dans expr */ + + inter = createExpr (XOR); + expr = CDR (expr); + while ((expr = CDR (expr))) + addHExpr (inter, copyExpr (CAR (expr))); + + dev = devXorExpr (inter); /* on developpe expr */ + freeExpr (inter); + + addQExpr (xor, dev); + dev = devXor2Expr (xor); + freeExpr (xor); + return (dev); + } + } +} + +/*------------------------------------------------------------------ + IDENT : devXor2Expr + ------------------------------------------------------------------ + FUNCTION : developpe un XOR 2 + a xor b = ((not a) and b) or (a and (not b)) + ------------------------------------------------------------------*/ +chain_list * +devXor2Expr (expr) + chain_list *expr; +{ + if (ATOM (expr) || OPER (expr) != XOR || lengthExpr (expr) > 2) + return (copyExpr (expr)); + else + { + chain_list *ret; + chain_list *and1, *and2; + chain_list *a, *b; + + a = CADR (expr); /* premier argument */ + b = CADR (CDR (expr)); /* deuxieme argument */ + ret = createExpr (OR); + and1 = createExpr (AND); + and2 = createExpr (AND); + addQExpr (and1, copyExpr (a)); + addQExpr (and2, copyExpr (b)); + + addQExpr (and1, notExpr (copyExpr (b))); + addQExpr (and2, notExpr (copyExpr (a))); + addQExpr (ret, and2); + addQExpr (ret, and1); + return ret; + } +} + + +/*------------------------------------------------------------------ + IDENT : flatPolarityExpr + ------------------------------------------------------------------ + FUNCTION : Reporte sur les entrees primaires (atomes) la negation + par applications successives des lois de Morgan et de + simplifications de l'algebre de Boole. + Si le signe est egal a 0 a l'appel, on obtient un + report sur la fonction inverse. + ------------------------------------------------------------------ */ +chain_list * +flatPolarityExpr (expr, signe) + chain_list *expr; + int signe; +{ + short oper; + chain_list *pt; + + if (ATOM (expr)) + if (signe) + return (createAtom (VALUE_ATOM (expr))); + else + { + pt = createExpr (NOT); + addQExpr (pt, createAtom (VALUE_ATOM (expr))); + return pt; + } + else + { + oper = OPER (expr); + if (oper == NOT) /* operateur NOT */ + { + expr = CADR (expr); + if (signe) + return (flatPolarityExpr (expr, 0)); + else + return (flatPolarityExpr (expr, 1)); + } + else + { + if (oper == OR || oper == AND) + { + if (signe) /* aucun changement a ce niveau */ + pt = createExpr (oper); + else + /* application des lois de Morgan */ if (oper == AND) + pt = createExpr (OR); + else + pt = createExpr (AND); + while ((expr = CDR (expr))) + addQExpr (pt, flatPolarityExpr (CAR (expr), signe)); + return (pt); + } + if (oper == NOR || oper == NAND) + { + pt = copyExpr (expr); + if (OPER (expr) == NOR) + changeOperExpr (pt, OR); + else + changeOperExpr (pt, AND); + if (signe) + expr = flatPolarityExpr (pt, 0); + else + expr = flatPolarityExpr (pt, 1); + freeExpr (pt); + return (expr); + } + printf ("flatPolarityExpr: error - unknown operator %s\n", operToChar (oper)); + exit (-1); + } + } +} + +/*------------------------------------------------------------------ + IDENT : flatArityExpr + ------------------------------------------------------------------ + FUNCTION : Ecrase une expression par elimination des operateurs redondants. + ------------------------------------------------------------------ */ +void +flatArityExpr (expr) + chain_list *expr; +{ + int oper; + chain_list *expr1, *expr2, *exprBefore; + + if (!ATOM (expr)) + { + oper = OPER (expr); + if (oper == NOT || oper == STABLE) + flatArityExpr (CADR (expr)); + else if (oper == NOR || oper == NAND || oper == NXOR) + { + expr1 = expr; + while ((expr1 = CDR (expr1))) + flatArityExpr (CAR (expr1)); + } + else + { + expr1 = expr; + exprBefore = expr; + while ((expr1 = CDR (expr1))) + { + expr2 = CAR (expr1); + if (!ATOM (expr2)) + { + if (oper == OPER (expr2)) /* detection OK */ + { + exprBefore->NEXT = CDR (expr2); + while (CDR (expr2)) + expr2 = CDR (expr2); + CDR (expr2) = CDR (expr1); + + CDR (expr1) = NULL; + expr2 = CAR (expr1); + CDR (expr2) = NULL; + freechain (expr1); + freechain (expr2); + expr1 = exprBefore; + } + else + { + flatArityExpr (expr2); + exprBefore = CDR (exprBefore); + } + } + else + exprBefore = CDR (exprBefore); + } + } + } +} + +/*------------------------------------------------------------------ + IDENT : supportChain_listExprInt + ------------------------------------------------------------------ + FUNCTION : renvoie le support d'une expression dans une liste chainee. + (1 seule occurence par variable). + ------------------------------------------------------------------ */ +void +supportChain_listExprInt (expr, ppCL) + chain_list *expr; + chain_list **ppCL; +{ + if (ATOM (expr)) + { + chain_list *pCL = *ppCL; + if (strcmp (VALUE_ATOM (expr), "'d'") && + strcmp (VALUE_ATOM (expr), "'1'") && + strcmp (VALUE_ATOM (expr), "'0'")) + { + while (pCL) /* recherche occurence */ + { + if ((char *) pCL->DATA == VALUE_ATOM (expr)) + return; + pCL = pCL->NEXT; + } + *ppCL = addchain (*ppCL, (void *) VALUE_ATOM (expr)); + } + } + else + { + while ((expr = CDR (expr))) + supportChain_listExprInt (CAR (expr), ppCL); + } +} + +/*------------------------------------------------------------------ + IDENT : supportChain_listExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le support d'une expression dans une liste chainee. + (1 seule occurence par variable). + ------------------------------------------------------------------ */ +chain_list * +supportChain_listExpr (expr) + chain_list *expr; +{ + chain_list **ppCL; + chain_list *res; + + ppCL = (chain_list **) mbkalloc (sizeof (chain_list *)); + *ppCL = NULL; + supportChain_listExprInt (expr, ppCL); + res = reverse (*ppCL); + mbkfree (ppCL); + + return res; +} + +/*------------------------------------------------------------------ + IDENT : supportPtype_listExprInt + ------------------------------------------------------------------ + FUNCTION : renvoie le support d'une expression dans une liste typee. + (1 seule occurence par variable). + ------------------------------------------------------------------ */ +void +supportPtype_listExprInt (expr, ppCL) + chain_list *expr; + ptype_list **ppCL; +{ + if (ATOM (expr)) + { + ptype_list *pCL = *ppCL; + if (strcmp (VALUE_ATOM (expr), "'d'") && + strcmp (VALUE_ATOM (expr), "'1'") && + strcmp (VALUE_ATOM (expr), "'0'")) + { + while (pCL) /* recherche occurence */ + { + if ((char *) pCL->DATA == VALUE_ATOM (expr)) + return; + pCL = pCL->NEXT; + } + *ppCL = addptype (*ppCL, 0, (void *) VALUE_ATOM (expr)); + } + } + else + { + while ((expr = CDR (expr))) + supportPtype_listExprInt (CAR (expr), ppCL); + } +} + +/*------------------------------------------------------------------ + IDENT : supportPtype_listExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le support d'une expression dans une liste typee. + (1 seule occurence par variable). + ------------------------------------------------------------------ */ +ptype_list * +supportPtype_listExpr (expr) + chain_list *expr; +{ + ptype_list **ppCL; + ptype_list *res; + + ppCL = (ptype_list **) mbkalloc (sizeof (ptype_list *)); + *ppCL = NULL; + supportPtype_listExprInt (expr, ppCL); + res = (ptype_list *) reverse ((chain_list *) * ppCL); + mbkfree (ppCL); + return (res); +} + +/*------------------------------------------------------------------ + IDENT : maxExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le max des arguments d'une expression avec une + fonction de comparaison func renvoyant un int. + ------------------------------------------------------------------ */ +chain_list * +maxExpr (expr, func) + chain_list *expr; + int (*func) (); +{ + chain_list *expr1; + + expr = CDR (expr); + expr1 = expr; + while ((expr = CDR (expr))) + if ((*func) (CAR (expr)) > (*func) (CAR (expr1))) + expr1 = expr; + + return CAR (expr1); +} + +/*------------------------------------------------------------------ + IDENT : minExpr + ------------------------------------------------------------------ + FUNCTION : renvoie le min des arguments d'une expression avec une + fonction de comparaison func renvoyant un int. + ------------------------------------------------------------------ */ + +chain_list * +minExpr (expr, func) + chain_list *expr; + int (*func) (); +{ + chain_list *expr1; + + expr = CDR (expr); + expr1 = expr; + while ((expr = CDR (expr))) + if ((*func) (CAR (expr)) < (*func) (CAR (expr1))) + expr1 = expr; + + return CAR (expr1); +} + +/*------------------------------------------------------------------ + IDENT : sortExpr + ------------------------------------------------------------------ + FUNCTION : trie les arguments d'une expression a partir d'une fonction + func renvoyant un int. + direction = 1 croissant ; direction = 0 decroissant + ------------------------------------------------------------------ */ +void +sortExpr (expr, func, direction) + chain_list *expr; + long (*func) (); + int direction; +{ + chain_list *expr1; + int okPermu = 1; + + if (!ATOM (expr)) /* ce n'est pas un atome */ + { + while (okPermu) + { + expr1 = CDR (expr); + okPermu = 0; + while (CDR (expr1)) + { + if ((direction == 1 && + ((*func) CAR (expr1) > (*func) CADR (expr1))) || + (direction == 0 && + ((*func) CAR (expr1) < (*func) CADR (expr1)))) + { + chain_list *permu; + + permu = CAR (expr1); + expr1->DATA = (void *) CADR (expr1); + (expr1->NEXT)->DATA = (void *) permu; + okPermu = 1; + } + expr1 = CDR (expr1); + } + } + } +} + +/*------------------------------------------------------------------ + IDENT : funcNormExpr + ------------------------------------------------------------------ + FUNCTION : normalise une expression a tous les niveaux + variable = pointeur d'allocation + expression = numero d'operateur. + ex : (and a (xor w g) b (or x f) (or e g o) (xor t h k)) + --> (and (or x f) (or e o g) (xor g w) (xor t h k) b a) + ------------------------------------------------------------------ */ +int +funcNormExpr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + return ((int) VALUE_ATOM (expr)); + else if (OPER (expr) == NOT) + if (ATOM (CADR (expr))) + return (NOT * 100 + 10); + else + return (NOT * 100 + OPER (CADR (expr))); + + return OPER (expr) * 100 + lengthExpr (expr); +} + +/*------------------------------------------------------------------ + IDENT : normExpr + ------------------------------------------------------------------ + FUNCTION : normalise une expression a tous les niveaux + variable = pointeur d'allocation + expression = numero d'operateur. + ex : (and a (xor w g) b (or x f) (or e g o) (xor t h k)) + --> (and (or x f) (or e o g) (xor g w) (xor t h k) b a) + ------------------------------------------------------------------ */ +void +normExpr (expr) + chain_list *expr; +{ + if (!ATOM (expr)) + { + sortExpr (expr, funcNormExpr, 1); + while ((expr = CDR (expr))) + normExpr (CAR (expr)); + } +} + +/*---------------------------------------------------------------------------- +deleteNumExpr : elimine le i-eme element de expr. + le premier argument commence a la place 0. +------------------------------------------------------ +parametres : un ABL et une place. +------------------------------------------------------- +return : rien. +----------------------------------------------------------------------------*/ +void +deleteNumExpr (expr, i) + chain_list *expr; + int i; +{ + int co = 0; + chain_list *e = expr, *pt; + + if (lengthExpr (expr) <= i) + { + printf ("deleteNumExpr : error - index %d out of bound for \n", i); + displayExpr (e); + exit (-1); + } + + pt = expr; + while ((i >= co) && (expr = CDR (expr))) + { + if (i == co) + { + CDR (pt) = CDR (expr); + CDR (expr) = NULL; /*desallocation du i-eme arg */ + freeExpr (CAR (expr)); + freechain (expr); + return; + } + else + pt = CDR (pt); + co++; + } +} + +/*---------------------------------------------------------------------------- +searchNumExpr : renvoie le i-eme element de expr. + le premier argument commence a la place 0. +------------------------------------------------------ +parametres : un ABL et une place. +------------------------------------------------------- +return : un chain_list * +----------------------------------------------------------------------------*/ +chain_list * +searchNumExpr (expr, i) + chain_list *expr; + int i; +{ + int co = 0; + chain_list *e = expr; + + while ((expr = CDR (expr))) + { + if (i == co) + return CAR (expr); + co++; + } + + printf ("\nsearchNumExpr : error - index %d out of bound for \n", i); + displayExpr (e); + exit (-1); +} + +/*---------------------------------------------------------------------------- +numberOccExpr : renvoie le nombre d'occurences d'une variable dans expr. +------------------------------------------------------ +parametres : un ABL et une variable. +------------------------------------------------------- +return : un int. +----------------------------------------------------------------------------*/ +int +numberOccExpr (exp, name) + chain_list *exp; + char *name; +{ + if (ATOM (exp)) + { + if ((int) name == (int) VALUE_ATOM (exp)) + return 1; + else + return 0; + } + else + { + int cpt = 0; + + while ((exp = CDR (exp))) + cpt += numberOccExpr (CAR (exp), name); + return cpt; + } +} + +/*---------------------------------------------------------------------------- +changeOperExpr : change l'operateur d'une expression +------------------------------------------------------ +parametres : un ABL +------------------------------------------------------- +return : un void. +----------------------------------------------------------------------------*/ +void +changeOperExpr (expr, oper) + chain_list *expr; + short oper; +{ + int op = (int) oper; + + if (ATOM (expr)) + { + printf ("changeOperExpr : error - atomic expression\n"); + exit (-1); + } + else + { + expr = CAR (expr); + expr->DATA = (void *) op; + } +} + +/*---------------------------------------------------------------------------- +simplif10Expr : simplifie une expression en eliminant les constantes 0 et 1. +------------------------------------------------------ +parametres : un ABL +------------------------------------------------------- +return : un ABL. +----------------------------------------------------------------------------*/ +chain_list * +simplif10Expr (expr) + chain_list *expr; +{ + if (ATOM (expr)) + { + return copyExpr (expr); + } + else + { + short oper = OPER (expr); + chain_list *auxExpr = createExpr (oper), *args, *res; + int cpt1 = 0; + + for (args = CDR (expr); args; args = CDR (args)) + { + res = simplif10Expr (CAR (args)); + if (!ATOM (res)) + { + if (oper == STABLE) + { + addQExpr (auxExpr, res); + return auxExpr; + } + /* simplif (not (not a)) -> a */ + + if ((oper == NOT) && (OPER (res) == NOT)) + { + freeExpr (auxExpr); + return notExpr (res); + } + else + addQExpr (auxExpr, res); + } + else + { + switch (oper) + { + case NOT: + if (!strcmp (VALUE_ATOM (res), "'0'")) + { + freeExpr (res); + return createAtom ("'1'"); + } + if (!strcmp (VALUE_ATOM (res), "'1'")) + { + freeExpr (res); + return createAtom ("'0'"); + } + addQExpr (auxExpr, res); + return auxExpr; + break; + + case STABLE: + addQExpr (auxExpr, res); + return auxExpr; + break; + + case AND: + if (!strcmp (VALUE_ATOM (res), "'0'")) + { + freeExpr (res); + return createAtom ("'0'"); + } + if (strcmp (VALUE_ATOM (res), "'1'")) + addQExpr (auxExpr, res); + break; + case NAND: + if (!strcmp (VALUE_ATOM (res), "'0'")) + { + freeExpr (res); + return createAtom ("'1'"); + } + if (strcmp (VALUE_ATOM (res), "'1'")) + addQExpr (auxExpr, res); + break; + case OR: + if (!strcmp (VALUE_ATOM (res), "'1'")) + { + freeExpr (res); + return createAtom ("'1'"); + } + if (strcmp (VALUE_ATOM (res), "'0'")) + addQExpr (auxExpr, res); + break; + case NOR: + if (!strcmp (VALUE_ATOM (res), "'1'")) + { + freeExpr (res); + return createAtom ("'0'"); + } + if (strcmp (VALUE_ATOM (res), "'0'")) + addQExpr (auxExpr, res); + break; + case XOR: + if (!strcmp (VALUE_ATOM (res), "'1'")) + cpt1++; + else if (strcmp (VALUE_ATOM (res), "'0'")) + addQExpr (auxExpr, res); + break; + case NXOR: + if (!strcmp (VALUE_ATOM (res), "'1'")) + cpt1++; + else if (strcmp (VALUE_ATOM (res), "'0'")) + addQExpr (auxExpr, res); + break; + } + } + } + /* cas des XOR */ + + if (((cpt1 % 2) == 1) && CDR (auxExpr)) + { + if (lengthExpr (auxExpr) < 2) + { + if (!CDR (auxExpr)) + return createAtom ("'1'"); + else + changeOperExpr (auxExpr, NOT); + } + else + { + chain_list *aux = createExpr (NOT); + addQExpr (aux, auxExpr); + auxExpr = aux; + } + } + /* expression normale */ + + if ((lengthExpr (auxExpr) > 1) || (OPER (auxExpr) == NOT)) + return auxExpr; + + /* traitement pas d'argument */ + if (!CDR (auxExpr)) + { + freeExpr (auxExpr); + if ((oper == NAND) || (oper == OR)) + return createAtom ("'0'"); + if ((oper == AND) || (oper == NOR)) + return createAtom ("'1'"); + if (oper == XOR) + if ((cpt1 % 2) == 1) + return createAtom ("'1'"); + else + return createAtom ("'0'"); + if (oper == NXOR) + if ((cpt1 % 2) == 1) + return createAtom ("'0'"); + else + return createAtom ("'1'"); + } + /* traitement 1 seul argument */ + + if ((oper == AND) || (oper == OR)) + return CADR (auxExpr); + if ((oper == NAND) || (oper == NOR)) + { + changeOperExpr (auxExpr, NOT); + return auxExpr; + } + if (oper == XOR) + if ((cpt1 % 2) == 1) + { + changeOperExpr (auxExpr, NOT); + return auxExpr; + } + else + return CADR (auxExpr); + if (oper == NXOR) + if ((cpt1 % 2) == 1) + return CADR (auxExpr); + else + { + changeOperExpr (auxExpr, NOT); + return auxExpr; + } + } + + printf ("## ERROR in simplif10Expr, %s.%d\n", __FILE__, __LINE__); + exit (-1); + +} + +/*---------------------------------------------------------------------------- +simplifNotExpr : simplifie une expression en appliquant (not (not a)) --> a +------------------------------------------------------ +parametres : un ABL +------------------------------------------------------- +return : un ABL. +----------------------------------------------------------------------------*/ +chain_list * +simplifNotExpr (exp) + chain_list *exp; +{ + if (ATOM (exp)) + return copyExpr (exp); + if (OPER (exp) == NOT) + { + if (!ATOM (CADR (exp)) && OPER (CADR (exp)) == NOT) /* (not (not a)) */ + return (simplifNotExpr (CADR (CADR (exp)))); + else + { + chain_list *expr = createExpr (NOT); + + addQExpr (expr, simplifNotExpr (CADR (exp))); + return expr; + } + } + else + { + return (mapCarExpr (simplifNotExpr, OPER (exp), exp)); + } +} + +/*---------------------------------------------------------------------------- +charToExprInt : analyse une chaine de caracteres decrivant une + equation logique et remplit l'expression de retour. +------------------------------------------------------- +parametres : char. +------------------------------------------------------- +return : expr. +----------------------------------------------------------------------------*/ +chain_list * +charToExprInt (stringExpr, cptCar) + char *stringExpr; + int *cptCar; +{ + char *tokOper; + char *tok; + char *tokenExpr (); + chain_list *expr; + + tok = tokenExpr (stringExpr, cptCar); + if (!tok) + { + printf ("charToExpr : error - bad string to convert\n"); + printf ("%s\n", stringExpr); + exit (-1); + } + + if (strcmp (tok, "(")) /* noeud terminal direct */ + { + return createAtom (tok); + } + + mbkfree (tok); + + tokOper = tokenExpr (stringExpr, cptCar); + if (!tokOper) + { + printf ("charToExpr : error - bad string to convert\n"); + printf ("%s\n", stringExpr); + exit (-1); + } + switch (*tokOper) + { + case 'o': + expr = createExpr (OR); + break; + case 'a': + expr = createExpr (AND); + break; + case 'x': + expr = createExpr (XOR); + break; + case 's': + expr = createExpr (STABLE); + break; + case 'n': + switch (*(tokOper + 2)) + { + case 't': + expr = createExpr (NOT); + break; + case 'r': + expr = createExpr (NOR); + break; + case 'n': + expr = createExpr (NAND); + break; + case 'o': + expr = createExpr (NXOR); + break; + default: + printf ("charToExpr : error - bad operator %s\n", tokOper); + exit (-1); + } + break; + default: + printf ("charToExpr : error - bad operator %s\n", tokOper); + exit (-1); + } + mbkfree (tokOper); + + tok = tokenExpr (stringExpr, cptCar); /* lecture des operandes */ + if (!tok) + { + printf ("charToExpr : error - bad string to convert\n"); + printf ("%s\n", stringExpr); + exit (-1); + } + + do + { + /* traitement des elements terminaux */ + + if (strcmp (tok, "(")) + { + addQExpr (expr, createAtom (tok)); + mbkfree (tok); + } + else + { + /* traitement des sous-expressions */ + + mbkfree (tok); + *cptCar = *cptCar - 1; /*compteur revient sur "(" */ + + addQExpr (expr, charToExprInt (stringExpr, cptCar)); + } + + tok = tokenExpr (stringExpr, cptCar); + if (!tok) + { + printf ("charToExpr : error - bad string to convert\n"); + printf ("%s\n", stringExpr); + exit (-1); + } + } + while (strcmp (tok, ")")); + mbkfree (tok); + + /* on applique maintenant l'operateur */ + + return (expr); +} + +/*---------------------------------------------------------------------------- +charToExpr : analyse une chaine de caracteres decrivant une + equation logique et remplit l'expression de retour. +------------------------------------------------------- +parametres : char. +------------------------------------------------------- +return : expr. +----------------------------------------------------------------------------*/ +chain_list * +charToExpr (stringExpr) + char *stringExpr; +{ + int cptCar = 0; + + return charToExprInt (stringExpr, &cptCar); +} + +/*---------------------------------------------------------------------------- +tokenExpr : cherche les tokenExprs. +------------------------------------------------------- +parametres : +------------------------------------------------------- +return : (, ), ou une chaine de caractere. +----------------------------------------------------------------------------*/ +char * +tokenExpr (stringExpr, cptCar) + char *stringExpr; + int *cptCar; +{ + char *tok; + int i; + int compteur = *cptCar; + + for (; isspace (stringExpr[compteur]); compteur++); /* suppression ds blancs */ + + if (stringExpr[compteur] == '\0') /* probleme ... */ + return (NULL); + + i = compteur; + + /* on avance jusqu'au prochain tokenExpr */ + + for (; isspace (stringExpr[i]) == 0 && strncmp (stringExpr + i, ")", 1) != 0 && strncmp (stringExpr + i, "(", 1) != 0; i++); + + /* parenthese ouvrante ou fermante */ + + if (!strncmp (stringExpr + compteur, "(", 1) || !strncmp (stringExpr + compteur, ")", 1)) + { + tok = (char *) mbkalloc (2); + strncpy (tok, stringExpr + i, 1); + tok[1] = '\0'; + compteur++; + *cptCar = compteur; + return (tok); + } + + /* operateur ou atome */ + + tok = (char *) mbkalloc (i - compteur + 1); + strncpy (tok, stringExpr + compteur, i - compteur + 1); + tok[i - compteur] = '\0'; + *cptCar = i; + return (tok); +} + +/*---------------------------------------------------------------------------- +PMExprInt : Pattern Matching entre expr et pattern + (and (not a) (not a)) avec le pattern (and x x) renvoie 1 +------------------------------------------------------------------------------ +retour : 0 ou 1 +----------------------------------------------------------------------------*/ int +PMExprInt (expr, pattern, bind) + chain_list *expr, *pattern; + ptype_list **bind; +{ + if (ATOM (pattern)) + { + ptype_list *find = getptype (*bind, VALUE_ATOM (pattern)); + + /* le couple existe deja */ + + if (find) + { + if (!equalExpr (expr, (chain_list *) find->DATA)) + return (0); + } + else + *bind = addptype (*bind, VALUE_ATOM (pattern), expr); + + return (1); + } + else + /* pattern n'est pas un atome */ + { + if (ATOM (expr)) + return (0); + else + /* expr n'est pas un atome */ + { + if (OPER (expr) != OPER (pattern)) + return (0); + + if (lengthExpr (expr) != lengthExpr (pattern)) + return (0); + + while ((pattern = CDR (pattern))) + { + expr = CDR (expr); + if (PMExprInt (CAR (expr), CAR (pattern), bind) == 0) + return (0); + } + return (1); + } + } +} + +/*---------------------------------------------------------------------------- +PMExpr : Pattern Matching entre expr et pattern + (and (not a) (not a)) avec le pattern (and x x) renvoie 1 +------------------------------------------------------------------------------ +retour : 0 ou 1 +----------------------------------------------------------------------------*/ +int +PMExpr (expr, pattern) + chain_list *expr, *pattern; +{ + int ret; + ptype_list *bind = NULL; + + /* on mettra dans "bind" le couple (char * pattern, expr) */ + + ret = PMExprInt (expr, pattern, &bind); + freeptype (bind); + + return ret; +} diff --git a/alliance/src/log/src/log_thash.c b/alliance/src/log/src/log_thash.c new file mode 100644 index 00000000..6c2c7eaa --- /dev/null +++ b/alliance/src/log/src/log_thash.c @@ -0,0 +1,379 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + + +#ident "$Id: log_thash.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + +/****************************************************************************/ +/* Produit : librairie TSH - Gestion de tables de hachage */ +/****************************************************************************/ + +#include +#include "mut.h" +#include "log.h" + +#undef MAX_CALLS +#define MAX_CALLS 20 + +/* les fonction de l'utilisateurs : + ------------------------------ + + a. creation de table + + pTH createTH(len) + int len; + + b. destruction de la table + + destroyTH(pTable) + pTH pTable; + + c. recherche d'un element + + int searchTH(pTable,key) + pTH pTable; + char *key; + + d. ajout d'un element (ecrasement de la valeur s'il existe deja un element + dans la table possedant la meme cle) + + int addTH(pTable,key,value) + pTH pTable; + char *key; + int value; + + e. test d'existence et ajout d'un element dans la table.( renvoie 0 si + l'element n'existait pas avant son ajout, 1 sinon). + + int addExistTH(pTable,key,value) + pTH pTable; + char *key; + int value; + + f. destruction d'un element + + int deleteTH(pTable,key) + pTH pTable; + char *key; + + g. affichage total d'une table avec la cle en %s et la valeur en %d. + + void displayTH(pTable) + pTH pTable; + + h. reallocation d'une table + + void reAllocTH(pTable) + pTH pTable ; + */ + +/*--------------- la fonction de base pour le hachage.---------------- */ + + +int +hashTH (pn) + char *pn; +{ + + /* return(abs((int) pn * ((int) pn >> 5) >> 4)); */ + return (((unsigned long) pn >> 2)); + +} + + /* creation d'une table de hachage */ + +pTH +createTH (len) + int len; +{ + pTH pTable; + pElemTH pEl; + int i; + + if (len <= 0) + { + printf ("createTH : error - length <= 0\n"); + exit (-1); + } + pTable = (pTH) mbkalloc (sizeof (struct tableTH)); + pTable->length = len; + + pEl = (pElemTH) mbkalloc (len * (sizeof (struct elemTH))); + pTable->pElem = pEl; + for (i = 0; i < len; i++) + { + pEl->key = NULL; + pEl->value = EMPTYTH; + pEl++; + } + pTable->count = 0; + return (pTable); +} + + /* destruction d'une table de hachage */ + +void +destroyTH (pTable) + pTH pTable; +{ + pElemTH pEl; + + pEl = pTable->pElem; + mbkfree (pEl); + mbkfree (pTable); +} + + /* recherche d'un element dans la table + renvoie -1 si la recherche echoue. */ + + +int +searchTH (pTable, key) + pTH pTable; + char *key; +{ + int co = 0; + int indice = 0; + pElemTH pEl; + + indice = hashTH (key) % pTable->length; + do + { + if (co++ > MAX_CALLS) + { + reAllocTH (pTable); + return (searchTH (pTable, key)); + } + + pEl = (pTable->pElem) + indice; + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + if ((int) key == (int) pEl->key) + return (pEl->value); + } + else if (pEl->value == EMPTYTH) + return (EMPTYTH); + indice = (indice + 1) % pTable->length; + } + while (1); +} + + + /* ajout d'un element a la table */ + +int +addTH (pTable, key, value) + pTH pTable; + char *key; + int value; +{ + int indice = 0; + pElemTH pEl; + int co = 0; + + if (value == EMPTYTH || value == DELETETH) + { + printf ("addTH : error - value is EMPTYTH or DELETETH\n"); + exit (-1); + } + if (pTable->count++ > (pTable->length) * 8 / 10) + { + reAllocTH (pTable); + return (addTH (pTable, key, value)); + } + + indice = hashTH (key) % pTable->length; + do + { + if (co++ > MAX_CALLS) + { + reAllocTH (pTable); + return (addTH (pTable, key, value)); + } + pEl = (pTable->pElem) + indice; + if (pEl->value == EMPTYTH || pEl->value == DELETETH) + { + pEl->value = value; + pEl->key = key; + return (value); + } + else if ((int) pEl->key == (int) key) + { + pTable->count--; + pEl->value = value; + return (value); + } + + indice = (indice + 1) % pTable->length; + } + while (1); +} + + /* test d'existence et ajout d'un element a la table */ + +int +addExistTH (pTable, key, value) + pTH pTable; + char *key; + int value; +{ + int indice = 0; + pElemTH pEl; + int co = 0; + + if (value == EMPTYTH || value == DELETETH) + { + printf ("addExistTH : error - value is EMPTYTH or DELETETH\n"); + exit (-1); + } + if (pTable->count++ > (pTable->length) * 8 / 10) + { + reAllocTH (pTable); + return (addExistTH (pTable, key, value)); + } + + indice = hashTH (key) % pTable->length; + do + { + if (co++ > MAX_CALLS) + { + reAllocTH (pTable); + return (addExistTH (pTable, key, value)); + } + pEl = (pTable->pElem) + indice; + if (pEl->value == EMPTYTH || pEl->value == DELETETH) + { + pEl->value = value; + pEl->key = key; + return (0); + } + else if ((int) pEl->key == (int) key) + { + pTable->count--; + pEl->value = value; + return (1); + } + + indice = (indice + 1) % pTable->length; + } + while (1); +} + + + + + /* elimination d'un element de la table */ + + +int +deleteTH (pTable, key) + pTH pTable; + char *key; +{ + int indice = 0; + pElemTH pEl; + int co = 0; + + indice = hashTH (key) % pTable->length; + do + { + if (co++ > MAX_CALLS) + { + reAllocTH (pTable); + return (deleteTH (pTable, key)); + } + pEl = (pTable->pElem) + indice; + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + if ((int) key == (int) pEl->key) + { + pTable->count--; + pEl->value = DELETETH; + return (pEl->value); + } + } + else if (pEl->value == EMPTYTH) + return (EMPTYTH); + indice = (indice + 1) % pTable->length; + } + while (1); /* on sort quand on arrive sur EMPTYTH */ +} + + +/* affichage des elements de la table */ + +void +displayTH (pTable) + pTH pTable; +{ + int i; + pElemTH pEl; + pEl = pTable->pElem; + printf ("================== DISPLAYTH ================\n"); + printf ("length = %d\t count = %d\n", pTable->length, pTable->count); + printf ("=============================================\n"); + for (i = 0; i < pTable->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + { + printf ("index %d\t", i); + printf ("key %s\t", pEl->key); + printf ("value %d \n", pEl->value); + } + pEl++; + } +} + +/********** reallocation table d'entiers **************/ + +void +reAllocTH (pTable) + pTH pTable; +{ + pTH tabBis; + pElemTH pEl; + int i; + + pEl = pTable->pElem; + tabBis = createTH ((pTable->length) * 5); + for (i = 0; i < pTable->length; i++) + { + if (pEl->value != EMPTYTH && pEl->value != DELETETH) + addTH (tabBis, pEl->key, pEl->value); + pEl++; + } + mbkfree (pTable->pElem); + pTable->length = tabBis->length; + pTable->pElem = tabBis->pElem; + pTable->count = tabBis->count; + mbkfree (tabBis); +} diff --git a/alliance/src/log/src/log_thashbdd.c b/alliance/src/log/src/log_thashbdd.c new file mode 100644 index 00000000..74c8bef1 --- /dev/null +++ b/alliance/src/log/src/log_thashbdd.c @@ -0,0 +1,352 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + +#ident "$Id: log_thashbdd.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + +/*-------------------------------------------------------------------------- + la table de hachage des BDD + la version du 10.12.90 + -------------------------------------------------------------------------- */ + +#include "mut.h" +#include "log.h" + +#undef NB_APPEL_MAX +#define NB_APPEL_MAX 50 + +/* les fonction de l'utilisateurs : + ------------------------------ + + initialisation au depart des pointeurs de vertex a NULL. + un pointeur de Vertex desalloue est mis a BDDDELETE. + Les fonctions qui utilisent le hachage peuvent renvoye BDDTABLE_PLEINE + si la table est trop remplie. + + a. creation de table + + pTableBdd createTableBdd(len) + int len; + + b. destruction de la table + + destroyTableBdd(pTab) + pTableBdd pTab; + + c. re-allocation d'une table de hachage + + reAllocTableBdd(pTab) + pTableBdd pTab; + + d. recherche d'un element + + pNode searchTableBdd(pTab,index,high,low) + pTableBdd pTab; + int index; + pNode high,low; + + e. ajout d'un element + + int addTableBdd(pTab,pBdd) + pTableBdd pTab; + pNode pBdd; + + f. destruction d'un element + + int deleteTableBdd(pTab,key) + pTableBdd pTab; + pNode pBdd; + + g. affichage total d'une table + + void displayBdd(pTab) + pTableBdd pTab; + + h. le garbage collector d'une table de hachage + + void gcTableBdd(pTab); + pTableBdd pTab; + + + */ + +/*-------------------- la fonction de hachage ---------------------------- */ + +int +hashBdd (index, high, low) + int index; + pNode high, low; +{ + return (abs (index + ((int) high << 1) + (int) low + + ((int) high >> 4) + ((int) low >> 5))); +} + +/*--------------- la fonction de changement de cle ------------------------- */ + +int +newKeyBdd (index, high, low) + int index; + pNode high, low; +{ + return (index + (index << 2) + (int) high + ((int) low << 1)); +} + +/*--------------- La table de hachage pour des BDD ------------ */ + +/* la fonction de creation de table de hachage pour les BDD . + On alloue en premier lieu une structure TABLE, puis une table + qui n'est rien d'autre qu'un tableau de pointeurs de BDD. Il est + donc possible de travailler avec plusieurs tables a la fois. */ + +pTableBdd +createTableBdd (len) + int len; +{ + pTableBdd pTab; + pNode *pBdd; + int i; + + if (!(pTab = (pTableBdd) mbkalloc (sizeof (struct tableBdd)))) + { + printf ("impossible allocation\n"); + exit (-1); + } + pTab->lenTableBdd = len; + + if (!(pBdd = (pNode *) mbkalloc (len * sizeof (pNode)))) + { + printf ("impossible allocation\n"); + exit (-1); + } + pTab->pBdd = pBdd; + for (i = 0; i < len; i++) + { + *pBdd = NULL; + pBdd++; + } + pTab->compteur = 0; + return (pTab); +} + + /* destruction d'une table de hachage */ + +void +destroyTableBdd (pTab) + pTableBdd pTab; +{ + pNode *pBdd; + + pBdd = pTab->pBdd; + mbkfree (pBdd); + mbkfree (pTab); +} + +/*------------------------------------------------------------------------------ +markBddLst :met a jour les marques de l'ensemble des graphes de LstGdb. +------------------------------------------------------- +parametres :une liste LstGdb. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ +/* + void markBddLst(pC,value) + pCircuit pC; + int value; + { + pNode pBdd; + + pEl = (pC->pTO)->pElemT ; + + for (i =0 ; i < (pC->pTO)->lenTable; i++) + { + if(pEl->value != VIDE && pEl->value != DELETE) + markBdd((pNode)pEl->value) ; + pEl++ ; + } + } + */ + + /* re-allocation d'une table de hachage devenue trop petite... */ + +pTableBdd +reAllocTableBdd (pTab) + pTableBdd pTab; +{ + int i; + pNode *pBdd; + pTableBdd pTabBis; + + if (pTab->lenTableBdd > MAX_SIZE_BDD) + { + printf ("BDD's system : not enough memory...\n"); + exit (-1); + } + pTabBis = createTableBdd (pTab->lenTableBdd * 3); /* trois fois plus grande */ + pBdd = pTab->pBdd; + for (i = 0; i < pTab->lenTableBdd; i++) + { + if (*pBdd != NULL && *pBdd != BDDDELETE) /* la recopie */ + addTableBdd (pTabBis, *pBdd); + pBdd++; + } + destroyTableBdd (pTab); + return (pTabBis); +} + + /* recherche d'un element dans la table + renvoie NULL si la recherche echoue. */ + +pNode +searchTableBdd (pTab, index, high, low) + pTableBdd pTab; + int index; + pNode high, low; +{ + int co = 0; + pNode pBddCur; + int key = index; + int indice; + + do + { + if (co++ > NB_APPEL_MAX) + return (BDDTABLE_PLEINE); + indice = hashBdd (key, high, low) % pTab->lenTableBdd; + pBddCur = *((pTab->pBdd) + indice); + if (pBddCur != NULL && pBddCur != BDDDELETE) + if (high == pBddCur->high && + low == pBddCur->low && + index == pBddCur->index) + return (pBddCur); + key = newKeyBdd (key, high, low); + } + while (pBddCur != NULL); + return (NULL); +} + + /* ajout d'un element a la table */ + + +int +addTableBdd (pTab, pBdd) + pTableBdd pTab; + pNode pBdd; +{ + int co = 0; + pNode *pBddCur; + int index = pBdd->index; + pNode high = pBdd->high; + pNode low = pBdd->low; + int key = index; + int indice; + + if (pTab->compteur++ > (pTab->lenTableBdd) * 8 / 10) /* remplissage au 8/10 */ + return (TABLE_PLEINE); + do + { + if (co++ > NB_APPEL_MAX) + return (TABLE_PLEINE); + indice = hashBdd (key, high, low) % pTab->lenTableBdd; + pBddCur = ((pTab->pBdd) + indice); + if (*pBddCur == NULL || *pBddCur == BDDDELETE) + { + *pBddCur = pBdd; + return (indice); /* retourne la place utilisee */ + } + key = newKeyBdd (key, high, low); + } + while (1); +} + + + /* elimination d'un element de la table */ + + +int +deleteTableBdd (pTab, pBdd) + pTableBdd pTab; + pNode pBdd; +{ + int co = 0; + pNode *pBddCur; + pNode high = pBdd->high; + pNode low = pBdd->low; + int key = pBdd->index; + int indice; + + do + { + if (co++ > NB_APPEL_MAX) + return (TABLE_PLEINE); + indice = hashBdd (key, high, low) % pTab->lenTableBdd; + pBddCur = (pTab->pBdd) + indice; + if (*pBddCur != NULL && *pBddCur != BDDDELETE) + { + if (pBdd == *pBddCur) + { + *pBddCur = BDDDELETE; + return (DELETE); + } + } + key = newKeyBdd (key, high, low); + } + while (pBddCur != NULL); + return ((int) NULL); +} + +/* affichage des elements de la table */ + +void +displayHashBdd (pTab) + pTableBdd pTab; +{ + int i; + int co = 0; + pNode *pBdd; + + pBdd = pTab->pBdd; + { + printf ("\n---------------------------------------------------------------"); + printf ("---------\n AFFICHAGE DE LA TABLE DE HACHAGE\n\n"); + } + for (i = 0; i < pTab->lenTableBdd; i++) + { + if (*pBdd != NULL && *pBdd != BDDDELETE) + { + co++; + printf ("****** indice %d ****** \n", i); + displayBdd (*pBdd , FALSE); + printf ("\n"); + } + pBdd++; + } + printf ("\n****** Nombre de noeuds dans la table = %d\n", co); +} diff --git a/alliance/src/log/src/log_thashloc.c b/alliance/src/log/src/log_thashloc.c new file mode 100644 index 00000000..1a7e1570 --- /dev/null +++ b/alliance/src/log/src/log_thashloc.c @@ -0,0 +1,241 @@ +/* + * This file is part of the Alliance CAD System + * Copyright (C) Laboratoire LIP6 - Département ASIM + * Universite Pierre et Marie Curie + * + * Home page : http://www-asim.lip6.fr/alliance/ + * E-mail support : mailto:alliance-support@asim.lip6.fr + * + * This progam is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Alliance VLSI CAD System 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 General Public License along + * with the GNU C Library; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Tool : ABL, BDD, HT Librarie + * Date : 1991,92 + * Author : Luc Burgun + * Modified by Czo 1996,97 + */ + + + +#ident "$Id: log_thashloc.c,v 1.1 2002/04/03 13:13:25 ludo Exp $" + +/*-------------------------------------------------------------------------- + la table de hachage local + la version du 14.12.90 + -------------------------------------------------------------------------- */ +#include "mut.h" +#include "log.h" + + +/* les fonction de l'utilisateurs : + ------------------------------ + + initialisation au depart des pointeurs de vertex a NULL. + Les fonctions qui utilisent le hachage peuvent renvoye DDBTABLE_PLEINE + si la table est trop remplie. + Il n'y a pas de destruction possible d'un element. + + a. creation de table + + pTableLoc createTabLoc(len) + int len; + + b. destruction de la table + + void destroyTabLoc(pTab) + pTableLoc pTab; + + c. re-allocation d'une table de hachage + + reAllocTabLoc(pTab) + pTableLoc pTab; + + d. recherche d'un element + + pNode searchTabLoc(pTab,high,low) + pTableLoc pTab; + pVertexLoc high,low; + + e. ajout d'un element + + int addTabLoc(pTab,pLoc) + pTableLoc pTab; + pVertexLoc pLoc; + + f. affichage total d'une table + + void displayLoc(pTab) + pTableLoc pTab; + + + */ + +/*-------------------- la fonction de hachage ---------------------------- */ + +int +hashLoc (high, low) + pNode high, low; +{ + return (abs (high->index + low->index + + (((int) high) >> 4) + (((int) low) >> 5) + + (int) high + (int) low)); +} + +/*--------------- La table de hachage pour des LOC ------------ */ + +/* la fonction de creation de table de hachage pour les LOC . + On alloue en premier lieu une structure TABLE, puis une table + qui n'est rien d'autre qu'un tableau de pointeurs de LOC. Il est + donc possible de travailler avec plusieurs table a la fois. */ + +pTableLoc +createTabLoc (len) + int len; +{ + pTableLoc pTab; + pVertexLoc pLoc; + int i; + + if (!(pTab = (pTableLoc) mbkalloc (sizeof (struct tableLoc)))) + { + printf ("allocation impossible\n"); + exit (-1); + } + pTab->lenTabLoc = len; + + if (!(pLoc = (pVertexLoc) mbkalloc (len * sizeof (struct vertexLoc)))) + { + printf ("allocation impossible\n"); + exit (-1); + } + pTab->pLoc = pLoc; + for (i = 0; i < len; i++) + { + pLoc->oper = EMPTYTH; /* -1 */ + pLoc++; + } + return (pTab); +} + + /* destruction d'une table de hachage */ + +void +destroyTabLoc (pTab) + pTableLoc pTab; +{ + mbkfree (pTab->pLoc); + mbkfree (pTab); +} + + /* recherche d'un element dans la table + renvoie NULL si la recherche echoue. */ + +pNode +searchTabLoc (pTab, high, low, oper) + pTableLoc pTab; + pNode high, low; + short oper; +{ + pVertexLoc pLoc; + int indice; + + /* un seul acces permis */ + + indice = hashLoc (high, low) % pTab->lenTabLoc; + pLoc = pTab->pLoc; + if (pLoc[indice].oper == oper) + if (high == pLoc[indice].high && low == pLoc[indice].low) + return (pLoc[indice].father); + return (NULL); +} + + /* ajout d'un element a la table */ + + +int +addTabLoc (pTab, high, low, father, oper) + pTableLoc pTab; + pNode high, low, father; + short oper; +{ + pVertexLoc pLoc; + int indice; + + /* un seul acces permis */ + + indice = hashLoc (high, low) % pTab->lenTabLoc; + pLoc = pTab->pLoc; + pLoc[indice].oper = oper; + pLoc[indice].high = high; + pLoc[indice].low = low; + pLoc[indice].father = father; + return (indice); /* retourne la place utilisee */ +} + + +/* affichage des elements de la table */ + +void +displayLoc (pTab) + pTableLoc pTab; +{ + int i; + int co = 0; + pVertexLoc pLoc; + + pLoc = pTab->pLoc; + + printf ("\n---------------------------------------------------------------"); + printf ("---------\n AFFICHAGE DE LA TABLE DE HACHAGE\n\n"); + + for (i = 0; i < pTab->lenTabLoc; i++) + { + if (pLoc[i].oper != EMPTYTH) + { + co++; + printf ("****** indice %d ****** \n", i); + printf ("HIGH %d LOW %d FATHER %d\n", (int) pLoc[i].high, (int) pLoc[i].low, (int) pLoc[i].father); + printf ("\n"); + } + } + printf ("\n****** Nombre de noeuds dans la table = %d\n", co); +} + + + +/*------------------------------------------------------------------------------ +videTabLoc :vide une table de hachage locale. +------------------------------------------------------- +parametres :une table de hashage locale. +------------------------------------------------------- +return :rien. +------------------------------------------------------------------------------*/ + +void +videTabLoc (pTab) + pTableLoc pTab; +{ + pVertexLoc pLoc; + int i; + + pLoc = pTab->pLoc; + + + for (i = 0; i < pTab->lenTabLoc; i++) + { + pLoc[i].oper = EMPTYTH; + } +}